私はリフレクションを使用して、抽象クラスを実装するクラスのリストを取得しようとしています。Detector
このリストの要素(タイプClass<T extends Detector>
)を別のクラスの型パラメータとしてDetectorWrapper<T extends Detector>
に使用して、そのクラス内でT
(つまりnew T(...)
を使用)を簡単にインスタンス化できるようにしたいと思います。これに対してリフレクションを使用することは可能ですか、代わりにClass<T>
をDetectorWrapper
に渡して、T
のインスタンスが必要なときにリフレクションを使用してコンストラクタを呼び出す必要がありますか?クラス<T>を型パラメータとして使用
答えて
タイプパラメータとしてClass
オブジェクトを使用する方法はありませんが、タイプパラメータはまったくインスタンス化できないもの、つまりnew T()
とは言えません。
ですから、その型のオブジェクトをインスタンス化するClass
オブジェクトが必要と型パラメータに関係を定義することがあります。
class DetectorWrapper<T extends Detector> {
final List<T> detectors;
DetectorWrapper(Class<? extends T>... types) {
ArrayList<T> result=new ArrayList<>(types.length);
try {
for(Class<? extends T> type: types) result.add(type.newInstance());
}catch(InstantiationException|IllegalAccessException ex) {
throw new IllegalArgumentException(ex);
}
this.detectors=result;
}
}
最も実用的な問題のために、DetectorWrapper
クラスの型パラメータが廃止されていますが、つまり、あなたは
class Detector {}
class Foo extends Detector {}
class Bar extends Detector {}
のようなクラスを持つ
class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Class<? extends Detector>... types) {
ArrayList<Detector> result=new ArrayList<>(types.length);
try {
for(Class<? extends Detector> type: types) result.add(type.newInstance());
}catch(InstantiationException|IllegalAccessException ex) {
throw new IllegalArgumentException(ex);
}
this.detectors=result;
}
}
を使用することができます
new DetectorWrapper(Foo.class, Bar.class)
でDetectorWrapper
をインスタンス化できます。
Class.newInstance()
は、引数なしのコンストラクタを前提としています。共通のコンストラクタシグネチャが分かっている場合は、代わりにtype.getConstructor(parameterTypes).newInstance(initargs);
を使用してください。上記と同じ設定を仮定し、new DetectorWrapper(Foo::new, Bar::new)
ようにインスタンス化することができる
class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Supplier<? extends Detector>... types) {
ArrayList<Detector> result=new ArrayList<>(types.length);
for(Supplier<? extends Detector> s: types) result.add(s.get());
this.detectors=result;
}
}
:
のJava 8では、より堅牢な、非反射の代替があります。
class DetectorWrapper {
final List<Detector> detectors;
DetectorWrapper(Supplier<? extends Detector>... types) {
detectors=Arrays.stream(types).map(Supplier::get).collect(Collectors.toList());
}
}
しかし、あなたは、実行時に動的にClass
オブジェクトを発見した場合、反射インスタンス化回避する方法はありません。
同等の代替の実装は次のようになります。
奇妙なことに、 '
'T 'が型パラメータを参照している場合、' new T() 'は動作できません。範囲や別の誤解の中におそらく異なる「T」があります。 「T.method」を使用して 'Detector 'の' static'メソッドを呼び出すことは効果がありません(もし 'T''が' Detector'に比べて型が少ないと思うなら 'import static'を考えてください)。 '@ SafeVarargs'をコンストラクタに追加するには、実際にプロダクションコードでそれをしたいと思っています... – Holger
- 1. C++:クラスの型をパラメータとして使用する
- 2. クラスの型をパラメータとして使用する方法は?
- 3. 基本クラスのジェネリックアクションのパラメータとして派生クラス型を使用
- 4. データ型(クラス型)をキーとしてキーとして使用
- 5. 汎用型パラメータをパラメータとして使用する
- 6. クラスを型パラメータとして使用する場合、別の型パラメータを含む場合もあります。
- 7. ArrayListで使用するパラメータとしてクラスの型を渡しますか?
- 8. 汎用パラメータを持つ抽象クラスと型パラメータを使用するメソッド
- 9. Reflection.Emitの型パラメータとしての放射型の使用
- 10. パラメータとしてクラス型を渡してそのインスタンスを生成
- 11. caliburn.microのIHandle <>でパラメータとしてgenenricクラスを使用する方法?
- 12. 型パラメータを使用した型キャスト
- 13. タイプ型クラスを使用して統一していないと型家族
- 14. "except"と同じ例外クラスをパラメータとして2回使用
- 15. FStreamクラスと文字列をパラメータとして使用
- 16. Scalaのクラス型パラメータ。
- 17. パラメータとしてプライベートネストされた型を使用する
- 18. C#のジェネリック型パラメータとしてエイリアス型を使用する方法
- 19. Scalaで型パラメータとして列挙型を使用できますか?
- 20. スカラ暗黙のクラスの型パラメータを使用するには?
- 21. 期待を考えると型クラスとサブクラス型パラメータ
- 22. 汎用パラメータとしての匿名クラス
- 23. 別のクラスのフィールド型を使用してパラメータ化されたクラスをインスタンス化します
- 24. 静的型はパラメータとして使用できません
- 25. 構造体またはクラスをパラメータとして使用する
- 26. C# - メソッドのパラメータとしてのクラスの型
- 27. F#:型パラメータとしてデフォルトのコンストラクタがないクラス?
- 28. 基本クラスをパラメータとして使用するテンプレートを使用する
- 29. ジェネリックとクラス<?列挙型<?>>、class.getEnumConstants対EnumSet.allOf(クラス)()拡張
- 30. 入れ子のクラス<MyInterface <T>>をAndroidのパラメータとして渡す
この質問はリンクされた質問の複製ではありません。私は検索でこれらの解決策を見つけましたが、私が望むものとは正反対です**。リンクされた質問では、タイプ「T」が検索される。私は与えられた反射パラメータ化型の型を問い合わせるのではなく、型パラメータとして反映型を使いたいと思います。私はこれを明確にするために質問を改善する方法がわからない。 –