6

型パラメーターを使用してクラスを初期化する際に問題が発生しています。これは Java の型推論の欠点のようです。これを回避する方法またはこれを達成するためのより良い方法があるかどうかを知りたいです。

public class ParentModel {}

public class ChildModel extends ParentModel {}

public class Service<E extends ParentModel, T extends Collection<E>> {
    private Class<T> classOfT;
    private Class<E> classOfE;

    public Service(Class<E> classOfE, Class<T> classOfT) {
        this.classOfE = classOfE;
        this.classOfT = classOfT;
    }
}

public class BusinessLogic {
    public void someLogic() {
        Service<ChildModel, ArrayList<ChildModel>> service = new 
            Service<ChildModel, ArrayList<ChildModel>>(ChildModel.class, ArrayList.class);
    }
}

コンパイル時エラーは次のBusinessLogic::someLogic()とおりです:

コンストラクタ Service<ChildModel, ArrayList<ChildModel>>(Class<ChildModel>, Class<ArrayList>) は未定義です

Java 7 にコンパイルされています。

4

2 に答える 2

2

Java のジェネリックは「消去によって」実装されるため、 はなくClass<ArrayList<ChildModel>>>Class<ArrayList>.

できることは、スーパータイプを許可することです。

Class<? super T> classOfT;
Class<? super E> classOfE;
public Service(Class<? super E> classOfE, Class<? super T> classOfT) {

または、クラスをダブルキャストすることもできます:

Class<ArrayList<Integer>> clazz =
    (Class<ArrayList<Integer>>) (Class<? super ArrayList>) 
    ArrayList.class;

ただし、注意してください: クラスはただArrayList- Java はジェネリックの実行時に追加の型チェックを実行しません。自分で見て:

ArrayList<Integer> a1 = new ArrayList<>();
ArrayList<Double> a2 = new ArrayList<>();
System.out.println(a1.getClass() == a2.getClass());

同じクラスです。実行時に、ジェネリックは実質的になくなります

于 2016-03-14T01:31:57.127 に答える