型引数は実行時に渡されないため、呼び出し元のコードはトークンClass<T>
を渡して実行時にオブジェクトを構築する必要があります。実行時にオブジェクトを再構築するために渡すことができるさまざまなオブジェクトがあるため、トークンと名付けました。次に例を示します。Class<T>
- a
String
、一緒に使用するClass.forName(name)
Class<T>
オブジェクト_
- 型 token 、つまり、引数が型変数でもワイルドカード (境界付きかどうかも問わない) でもないパラメータ化された型の
new List<String>(){}
サブクラスnew
。
タイプ トークンの場合:
public class MyGenericDAO<T> {
@SuppressWarnings("unchecked")
public Class<T> getTypeParameter() throws Exception {
Type type = ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
return (Class<T>) type;
}
}
Type
を にキャストすると、未チェックの変換があることに注意してくださいClass<T>
。呼び出しコードは次のようになります。
MyGenericDAO<Foo> dao = new MyGenericDAO<Foo>(){};
// Then if you want an instance
Foo foo = dao.getTypeParameter().newInstance();
ここでも、中括弧に注意してください。スーパー タイプ トークンは、コンパイル時に生成された実際のクラスがある場合にのみ機能するためです。このアプローチは、クライアント コードがコントラクトを尊重し、DAO オブジェクトが必要になるたびに匿名の内部クラスを使用する場合にのみ機能します (それ以外の場合は魔法がgetTypeParameter()
消えます) 。