型パラメータを文字通り正しく使用することはできません。つまり、T.class
またはnew T()
などの表現は動作しません。なぜなら、「プログラムによって」ジェネリック型をあまり扱うことができないからです。すなわち
foostr.getClass() == foobar.getClass() == Foo.class
その結果、クラスリテラルを許可するにはポイントがありません、
Foo<String> foostr...;
Foo<Bar> foobar...;
我々は同じClass
オブジェクトを持っています:パラメータ化のタイプは、このようにFoo<T>
タイプの次のインスタンスのために、コンパイル後に自分の型パラメータを失いますFoo<String>.class
またはFoo<Bar>.class
などです。
これは、コンパイルタイプでのジェネリックタイプの多くの制限の背後にある理由です。実行時にタイプ引数についての情報がないため(イレーズタイプ)、コンパイル時に多くの可能性を制限する必要があります。
一つの可能性クラスFoo
ParameterizedType
とオブジェクトとしての型引数Bar
、例えば情報を抽出され、実行時にジェネリック型で動作します
:
class Bar {
...
}
class Foo<T> {
...
}
class Foobar extends Foo<Bar> {
ParameterizedType getFoobar() {
return (ParameterizedType)getClass().getGenericSuperclass();
}
}
...
Foobar foobar = new Foobar();
System.out.println(foobar.getFoobar().getRawType()); // Foo.class
System.out.println(foobar.getFoobar().getActualTypeArguments()[0]); // Bar.class
別のアプローチ最初のものに基づいていますが、実装が簡単ですは、パラメータ化タイプをキャプチャするFasterXML Jacsonプロジェクトから(または独自のクラスを作成します)TypeReference
の使用であります
class Foo<T> { ... }
class Bar { ... }
TypeReference typeReference = new TypeReference<Foo<Bar>>() {};
ParameterizedTypeImpl parametrizedType = (ParameterizedTypeImpl) typeReference.getType();
System.out.println(parametrizedType.getTypeName()); // Foo<Bar>
System.out.println(parametrizedType.getRawType()); // Foo
System.out.println(parametrizedType.getActualTypeArguments()[0]); // Bar
詳細についてはParameterizedTypeImpl#toString()
メソッドの実装をご覧ください。
私はあなたが正しく理解していれば、実際には存在しないタイプを返そうとしているので、これは可能ではないとは思わない...タイプのクラスはありません>動的に束縛される。しかし100%確かではありません。 –
...明確にするために、ジェネリック型が 'Bar'のクラス' Foo'を持っていると仮定しています。 'Foo'と' Bar'のそれぞれの型を含む 'Class'の後ろにいますか? –
@JSmithはい、そうです。 –