私は次のようなクラスがありますクラス<T>を実行時にクラス<T extends Foo>のように動作させるにはどうすればよいですか?
class FooClassAnalyser<T extends Foo> extends ClassAnalyser<T>
(ClassAnalyser
は、具体的な実装の数の抽象基底クラスであり、FooClassAnalyser
がT
はFoo
を拡張する場合に特化しています具体的な実装であるが)。それはこのようになりますコンストラクタがあります別のクラスにおいて
FooClassAnalyser(Class<T> classToAnalyse)
を、私はclassToAnalyse
の種類に応じて適切なコンストラクタを呼び出しClassAnalyser
のための静的なファクトリメソッドを持っている:
static <U> ClassAnalyser<U> constructClassAnalyser(Class<U> classToAnalyse)
機能私は、U instanceof Foo
かどうかを確認し、FooClassAnalyser
を作成して返します。
しかし、私はこれをJavaの型システム内に収める方法を見つけることができません。タイプ消去とは、U
で直接賢明なことを行うことはできないということです。
if (Foo.class.isAssignableFrom(classToAnalyse))
私の問題はinstanceof
とは違って、これは「instanceofの反射を経て」には見えないということです。しかし、我々は引数が、それを可能にするようにclassToAnalyse
を渡すことは、リフレクションを使用して経由U instanceof Foo
かどうかをテストしますJavaの型システム。特に、classToAnalyse
が実際にClass<U extends Foo>
であることをJavaが知らないため、FooClassAnalyser
のコンストラクタへの引数として直接classToAnalyse
を渡すと型の不一致が発生します。
私がこれまでに見つけた最良の解決策はclassToAnalyse
Class<? extends Foo>
を作るために未チェックのキャストを使用することです(それが確認さ実際ですが、Javaの気づいていないことが確認されていますということ)。少なくともそれをnew FooClassAnalyser
の引数として渡して、FooClassAnalyser<?>
オブジェクトを返すことが可能です。しかし、この問題は、ClassAnalyser<U>
に変換されません。なぜなら、Javaでは、classToAnalyse
に汎用バインディングが異なることを認識しないため、Class
オブジェクトがまだ同じオブジェクトであるという事実は変わりませんしたがって、依然としてClass<U>
である)。言い換えれば、Javaが認識できるすべてのFooClassAnalyser<?>
もまたFooClassAnalyser<U>
であるため、変換後に別のチェックされていないキャストが必要です。結果はコンパイルされて実行されるコードですが、型の安全性に関する多数の警告があります。
私が試みた他の多くのものは、構文エラーです(たとえば、Class<U extends Foo>
の変数は直接宣言できません; Javaでは正しく解析されません)。私は実際にはいずれの時点でもタイプU
のオブジェクトを持っていないことに注意してください。私はクラス自体を分析しようとしているので、作業するオブジェクトはClass<U>
しかありません。
タイプセーフな方法でこのようなコードを書くことは可能ですか?
価値があることは、私があなたがすでにやっているもの(チェックされていないキャストで)よりもうまくいくとは思わない。 Javaのジェネリックで少し前進したときにはいつも辛辣になってしまいます。 – kaqqao
注釈として、 'Class <? 'へのチェックされていないキャストを使う必要はありません。 Foo> 'を拡張します。 ['clazz.asSubclass(Foo.class)'](http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#asSubclass-java.lang.Class- )。 – Radiodef
@Radiodef:はい、 'clazz.asSubclass(Foo.class)'は 'Class <? 'Foo>は' 'についての知識を失ってしまいました。あなたは、 'FooClassAnalyser <? Fooを安全に警告なしで拡張しますが、ClassAnalyser '... – Holger