Java ジェネリックの処理のため、Class<List<Integer>>
クラスを取得することはできませんが (チェックされていないキャストなしで)、Class<List>
orになりますClass<List<?>>
。
したがって、 でパラメーター化された型を使用している場合は、メソッドを
2 つの例ElementProcessor
に変更することをお勧めします。Class<? super T> getElementClass()
interface MyElementProcessor<T> {
void doSomethingWith(T element);
Class<? super T> getElementClass();
/* more functions... */
}
SimpleElementProcessor implements MyElementProcessor<Integer> {
public void doSomethingWith(Collection<Integer> element) { /* ... */ }
public Class<Integer> getElementsClass() {
return Integer.class;
}
}
CollectionElementProcessor<E> implements MyElementProcessor<Collection<E>> {
public void doSomethingWith(Collection<Collection<E>> element) { /* ... */ }
// This works because Class<Collection<?>> is a valid substitute for Class<? super T>
public Class<Collection<?>> getElementsClass() {
return (Class<Collection<?>>) Collection.class; // Maybe the cast isn't needed
}
}
要素クラスの取得に関しては、リフレクションを使用できます。タイプがMyElementProcessor を派生させる場合、次のように取得できます。
for(Type interface : getClass().getGenericInterfaces()) {
if(interface instanceof ParameterizedType && ((ParameterizedType) interface).getRawType == MyElementProcessor.class)
Type myElementsType = ((ParameterizedType) interface).getActualTypeArguments()[0];
これは、派生クラス、つまり、匿名クラスまたは宣言された型に対してのみ機能します。型消去のためにこのように使用すると機能しません(この例はダミーです:これは単なる例です) :
public <T> MyElementProcessor newInstance() {
return new MyElementProcessor<T> {
// overridden methods ...
};
}
このような場合、次のいずれかを行います。
- ParameterizedType を取得するのではなく、型引数が TypeVariable であり、実際の型の実装を提供しない MyElementProcessor.class を直接取得します。
- 生の型が MyElementProcessor で、実際の型引数が TypeVariable である ParameterizedType を取得します