【问题标题】:How to instantiate generic variable like Class<Foo<T>>?如何实例化像 Class<Foo<T>> 这样的泛型变量?
【发布时间】:2010-01-13 12:11:10
【问题描述】:

我需要实例化像 Class> 这样的泛型变量。 例如,

Class<? extends List<String>> = ...

变体 1:

Class<? extends List<String>> clazz = LinkedList.class;

不工作 - “不兼容的类型”。

变体 2:

Class<? extends List> clazz = LinkedList.class;

工作,但在这种情况下 List 是原始类型 - 不好。

如何实例化这样的变量?

【问题讨论】:

标签: java generics


【解决方案1】:

拥有Class&lt;List&lt;String&gt;&gt; 并没有什么意义,因为它等同于Class&lt;List&lt;Integer&gt;&gt;(由于擦除,两者都是对原始列表的引用)。

话虽如此,如果您打算表示List&lt;String&gt; 类型,这是可能的,请参阅Google GuiceTypeLiteral

TypeLiteral<List<String>> type = new TypeLiteral<List<String>>() {};
System.out.println(type.getType()); //should print List<String>

使其成为可能的机制是对静态类型声明的反射,在类定义(class X extends Foo&lt;Y&gt;,Y 可通过反射获得,它保存在字节码中)、方法定义等中。TypeLiteral 使用前者,你可能会注意到它创建了一个全新的类,因此最终效果是您的类型参数被保留了。当您真正反对擦除时,这是一个很好的解决方法。

【讨论】:

    【解决方案2】:

    你无法做到正确。要么使用原始类型,要么使用不安全的类型转换。

    【讨论】:

    • @downvoter - 也许您没有理解“或使用不安全的演员表”实际上是公认答案的含义?
    【解决方案3】:
    List<String> myList = new ArrayList<String>();
    Class<? extends List<String>> var = (Class<? extends List<String>>)myList.getClass();
    

    【讨论】:

    • 只能通过创建不必要的对象并使用getClass()方法?
    • 对象真的没必要,单独演员就行了。
    • 嗯...需要不必要的对象:类 extends List> listClass = (Class extends List>) ArrayList.class;编译错误 - 不可转换的类型。
    【解决方案4】:

    你可以写:

        class ListString extends java.util.LinkedList<String> { }
        Class<? extends java.util.List<String>> clazz = ListString.class;
    

    但是,考虑到Class 所代表的含义,没有那么多意义。你最好尽可能避免反思。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多