1

自己境界のジェネリックサブタイプを持つ自己境界のジェネリック型に問題があります。

ある種のビルダーパターンを実装しようとしていますが、メインメソッドとほぼ同じようにステートメントを作成したいと思います。

ジェネリックを宣言する理由を見つけて、キャストが不要になり、ステートメントでコンパイルエラーが発生しないようにするために、誰かが私を助けてくれますか?または、なぜこれが機能しないのかを明確なテキストで説明できますか?

import java.util.Date;

public class SelfBoundingGenericTypeTest {
    public static void main(String[] args) {
        ConcreteType type = new ConcreteType().pageSize(1).id(12);

        SubType type2 = (SubType) new SubType().id(10).pageSize(0); // Why do i need the cast?

        SubType type3 = new SubType().pageSize(0).id(10); // Compile error
    }
}

abstract class SuperType<E extends SuperType<E>> {
    private int _pageSize = Integer.MIN_VALUE;
    private int _startIndex = Integer.MIN_VALUE;

    @SuppressWarnings("unchecked")
    public E pageSize(int value) {
        this._pageSize = value;
        return (E) this;
    }

    @SuppressWarnings("unchecked")
    public E startIndex(int value) {
        this._startIndex = value;
        return (E) this;
    }

    public int getPageSize() {
        return _pageSize;
    }

    public int getStartIndex() {
        return _startIndex;
    }
}

class SubType<E extends SubType<E>> extends SuperType<E> {
    private long _id = Long.MIN_VALUE;

    @SuppressWarnings("unchecked")
    public E id(long value) {
        this._id = value;
        return (E) this;
    }

    public long getId() {
        return _id;
    }
}

class ConcreteType extends SubType<ConcreteType> {
    private Date _startDate;

    public Date getStartDate() {
        return _startDate;
    }

    public ConcreteType startDate(Date value) {
        this._startDate = value;
        return this;
    }
}
4

2 に答える 2

1

SubTypeは生の型であるため、キャストが必要です。そのため、 から継承されたものを含め、すべてのメンバーは rawSuperTypeです。の生の署名SuperType.pageSizeはその消去SuperType pageSize(int)です。したがって、「修正」は生の型を使用しないことです。これはすべて魔法のように動作しConcreteTypeます。

編集:生の型を使用しないでください。これまで。を使用する必要がありますConcreteTypeが、すべてのメソッドを再宣言するという愚かで馬鹿げた、ばかげた「解決策」を使用する前に、((SubType<?>) new SubType())代わりに使用してください。

于 2012-08-28T08:50:39.210 に答える
0

失敗の理由についてはよくわかりませんが、それは私の理解です:abstract class SuperType> { public E pageSize(int value) { ...} }

メソッド pageSize の場合、E として宣言したようextends SuperType<E>に、型消去後、メソッド シグネチャは実際には であり、pageSize が SuperType を返すためSuperType pageSize(int)、問題が発生しました。new SubType().pageSize(0).id(10)

期待するほど魔法のようには見えませんが、共変の戻り値の型を使用すると、継承されたクラスでこれらのメソッドを単純に「オーバーロード」できます。

import java.util.Date;

public class SelfBoundingGenericTypeTest {
    public static void main(String[] args) {
        ConcreteType type = new ConcreteType().pageSize(1).id(12);

        SubType type2 = new SubType().id(10).pageSize(0); // works fine now

        SubType type3 = new SubType().pageSize(0).id(10); // works fine too
    }
}

abstract class SuperType {
    private int _pageSize = Integer.MIN_VALUE;
    private int _startIndex = Integer.MIN_VALUE;

    public SuperType pageSize(int value) {
        this._pageSize = value;
        return this;
    }

    public SuperType startIndex(int value) {
        this._startIndex = value;
        return this;
    }

    public int getPageSize() {
        return _pageSize;
    }

    public int getStartIndex() {
        return _startIndex;
    }
}

class SubType extends SuperType {
    private long _id = Long.MIN_VALUE;

    public SubType id(long value) {
        this._id = value;
        return this;
    }

    public SubType pageSize(int value) {
        return (SubType) super.pageSize(value);
    }

    public SuperType startIndex(int value) {
        return (SubType) super.pageSize(value);
    }

    public long getId() {
        return _id;
    }
}

class ConcreteType extends SubType {
    private Date _startDate;

    public Date getStartDate() {
        return _startDate;
    }

    public ConcreteType startDate(Date value) {
        this._startDate = value;
        return this;
    }

    public ConcreteType id(long value) {
        return (ConcreteType) super.id(value);
    }

    public ConcreteType pageSize(int value) {
        return (ConcreteType) super.pageSize(value);
    }

    public ConcreteType startIndex(int value) {
        return (ConcreteType) super.pageSize(value);
    }

}
于 2012-08-28T09:06:11.657 に答える