2

私たちは作ることができますclass Foo <T>、なぜ私は電話できないのnew T()ですか?理解しようとしましたが、それが型変数であることはわかっていTますが、その答えは得られませんでした...友人から尋ねられたので、答えも知りたがっています...よろしくお願いします。

4

3 に答える 3

7

型消去によるものです。Tのクラスは、実行時ではなく、コンパイル時にのみ認識されます。

回避策があります。タイプのメソッドパラメータを追加して、そのパラメータClass<T>を呼び出すnewInstanceことができます。これを試す前に、熟考のためにドキュメントを読んでください。そうでなければ、何に取り組んでいるのかを知ってください。

于 2012-08-01T12:37:18.627 に答える
2

Tがインスタンス化可能かどうかさえわからないため、プライベートコンストラクターを持つことができます。

想像:

class Foo<T> {

    public Foo() {
        new T();
    }
}

class Bar {
    private Bar() {}
}

class FooBar {
    public FooBar() {
       Foo<Bar> foo = new Foo<>();
    }
}
于 2012-08-01T12:37:26.317 に答える
0

問題は、前述の型消去ですが、Taymonです。いくつかのリフレクションとサブクラス化を使用して回避できるため、タイプ情報は実行時に残ります。

Barでは機能しますが、Quxでは機能しないことに注意してください。Barは、コンパイル時に、固定型引数Bazを使用してFooを拡張することにより、型パラメーターを指定していることに注意してください。インスタンス化は、アクセス可能なゼロ引数コンストラクターにも依存します。

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import sun.reflect.generics.reflectiveObjects.TypeVariableImpl;

// Made abstract so we can use getClass().getGenericSuperclass() and rely on subclasses
// specifying it's type parameter.
public abstract class Foo<T> {
    public T instantiateTypeParameter() throws Exception {
        Type type = getClass().getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType paramType = (ParameterizedType) type;

            Type typeArg = paramType.getActualTypeArguments()[0]; // We know it's only one, T
            if (typeArg instanceof TypeVariableImpl) {
                // Type is not specified. Can't do anything to retrieve it at runtime
                TypeVariableImpl typeVar = (TypeVariableImpl) typeArg;
                for (TypeVariable var : typeVar.getGenericDeclaration().getTypeParameters()) {
                    System.out.println("Type: " + var);
                }
                return null;
            } else {
                Class<?> clazz = (Class<?>) typeArg;
                return (T) clazz.getConstructor().newInstance();
            }
        } else {
            System.out.println("IMPOSSIBRUUU");
            return null;
        }
    }
}

public class Bar extends Foo<Baz> {
}

public class Qux<T> extends Foo<T> {
}

public static void main(String[] args) throws Exception {
    Bar bar = new Bar();
    Baz baz = bar.instantiateTypeParameter(); // Note that you know that it returns Baz
    System.out.println("Baz: " + baz); // It works!

    Qux<Baz> qux = new Qux<Baz>();
    Baz baz2 = qux.instantiateTypeParameter(); // Will be null
    System.out.println("Baz2: " + baz2);
}
于 2012-08-01T13:46:39.523 に答える