0

私は次のコードを持っています。これ<T extends Buffer>は、本当に意味することを理解しているので、今日これにリファクタリングしたばかりです。簡略化されたバージョンは次のとおりです。

public class Buffer {
    protected final int bufferType;
    protected final int bufferDataType;

    protected int bufferId;
    protected boolean created;

    public Buffer(final int bufferType, final int bufferDataType) {
        this.bufferType = bufferType;
        this.bufferDataType = bufferDataType;
    }

    public <T extends Buffer> T create() {
        assertNotCreated();
        bufferId = GL15.glGenBuffers();

        created = true;
        return (T)this;
    }

    public boolean hasBeenCreated() {
        return created;
    }

    private void assertNotCreated() {
        if (hasBeenCreated()) {
            throw new RuntimeException("Buffer has been created already.");
        }
    }
}

public class ArrayBuffer extends Buffer {
    public ArrayBuffer(final int bufferDataType) {
        super(GL15.GL_ARRAY_BUFFER, bufferDataType);
    }    
}

public class DynamicDrawArrayBuffer extends ArrayBuffer {
    public DynamicDrawArrayBuffer() {
        super(GL15.GL_DYNAMIC_DRAW);
    }
}

で警告が発生しました。Buffer.create()警告を抑制しても安全ですか? より安全にする方法はありますか?

もう 1 つの要件は、この API の呼び出し/使用コードに乱雑さを追加しないことです。具体的には、これは、DynamicDrawArrayBufferジェネリックがアタッチされていない可能性があることを意味します。

4

2 に答える 2

4

これは明らかにタイプセーフではありません。あなたは書ける

ArrayBuffer a = new ArrayBuffer(0);
DynamicDrawArrayBuffer d = a.create();

これにより、 が発生しClassCastExceptionます。メソッドの戻り値の型はcreate、呼び出しサイトから推測されます。そして、ここの呼び出しサイトで入手できる唯一の情報は、戻り値が a でなければならないということDynamicDrawArrayBufferですArrayBuffer

ここで共分散を簡単に利用できると思います。createメソッドは常にクラスの型を返すことができます。メソッドの戻り値の型は、メソッドを呼び出しcreateたときに取得した型情報によって決まります。

public class BufferTest
{
    public static void main(String[] args)
    {
        ArrayBuffer a = new ArrayBuffer();
        ArrayBuffer aa = a.create(); // Yes
        // DynamicDrawArrayBuffer ad = a.create(); // No

        DynamicDrawArrayBuffer d = new DynamicDrawArrayBuffer();
        ArrayBuffer da = a.create(); // Yes
        DynamicDrawArrayBuffer dd = d.create(); // Yes

        Buffer b = a;
        Buffer bb = b.create(); // Yes
        //ArrayBuffer ba = b.create(); // No
    }
}

class Buffer 
{
    public Buffer create() 
    {
        // create etc...
        return this;
    }

}

class DynamicDrawArrayBuffer extends ArrayBuffer 
{
    @Override
    public DynamicDrawArrayBuffer create()
    {
        super.create();
        return this;
    }
}

class ArrayBuffer extends Buffer 
{
    @Override
    public ArrayBuffer create()
    {
        super.create();
        return this;
    }
}
于 2014-03-19T09:43:14.907 に答える