1. ホーム
  2. java

[解決済み] なぜJavaにreified genericsがないことを気にしなければならないのか?

2022-12-16 05:43:18

疑問点

これは、最近面接で、候補者がJava言語に追加してほしいものとして質問したときに出てきたものです。一般的に Java にない痛みとして認識されている 再定義されたジェネリックス がないことが苦痛であると一般に認識されていますが、それを押し付けられた候補者は、それがあれば実現できたであろうことの種類を実際に私に話すことができませんでした。

明らかに、Java では生の型が許可されているため (そして安全でないチェック)、ジェネリックスを破壊することが可能で、最終的には List<Integer> を含んでしまうことがあります。 String s. これは明らかに型情報を再定義した場合に不可能となる可能性があります。 が、これ以上のものがあるはずです。 !

以下のような例を投稿していただけませんか? 本当にやりたいこと の例を投稿してもらえますか?つまり、明らかにあなたは List の型を取得することはできますが、それを使って何をするのでしょうか?

public <T> void foo(List<T> l) {
   if (l.getGenericType() == Integer.class) {
       //yeah baby! err, what now?

EDIT : 回答が主に Class をパラメータとして渡す必要性についてです (例えば EnumSet.noneOf(TimeUnit.class) ). 私はどちらかというと、次のようなものを探していました。 のようなものを探していました。 . 例えば

List<?> l1 = api.gimmeAList();
List<?> l2 = api.gimmeAnotherList();

if (l1.getGenericType().isAssignableFrom(l2.getGenericType())) {
    l1.addAll(l2); //why on earth would I be doing this anyway?

どのように解決するのですか?

私が何度か遭遇したこの「必要性」は、結局のところ、次のような構成に集約されます。

public class Foo<T> {

    private T t;

    public Foo() {
        this.t = new T(); // Help?
    }

}

これは、C#では T には デフォルト のコンストラクタを使用します。によって実行時の型を取得することもできます。 typeof(T) でコンストラクタを取得し Type.GetConstructor() .

一般的なJavaの解決策としては Class<T> を引数として渡すことです。

public class Foo<T> {

    private T t;

    public Foo(Class<T> cls) throws Exception {
        this.t = cls.newInstance();
    }

}

(必ずしもコンストラクタの引数として渡す必要はなく、メソッドの引数でもかまいません。 try-catch は省略しています)

他のすべての一般的な型構成については、実際の型はリフレクションの少しの助けで簡単に解決することができます。以下のQ&Aは、使用例と可能性を示しています。