如何在Java中使用`MyClass <string> .class`?</string>

时间:2011-03-05 22:17:53

标签: java generics

如何使用public <T> T doit(Class<T> clazz);作为clazz来调用MyClass<String>.class我无法实例化或扩展MyClass。

编辑:“David Winslow”和“bmargulies”的回答是正确的(MyClass<String>) doit(MyClass.class);适用于原始问题但令人惊讶的是,当方法返回说MyClass<T>而不是T时,不会编译任何更多。

编辑:我已将MyClass替换为List并将条件添加到原始问题中。

6 个答案:

答案 0 :(得分:14)

使用List.class。由于Java类的type erasure类型参数完全是编译时构造 - 即使List<String>.class是有效语法,它也是与<{1}完全相同的类因为反射本质上是一个运行时的东西,所以它不能很好地处理类型参数(在Java中实现)。

如果要使用Class对象(例如)实例化一个新的List实例,可以将该操作的结果转换为具有相应的类型参数。

List<Date>.class

答案 1 :(得分:5)

例如,我已经多次询问过类似的问题 Acquiring generic class type

构造静态泛型类型有合理的理由。在操作上,他可能会喜欢

MyClass<String> result = doit(MyClass<String>.class);

如果没有语言语法支持,强制转换是正确的方法。如果经常需要这样做,那么铸件应该放在一个方法中,如

public class MyClass<T>
{
    @SuppressWarnings("unchecked")
    // may need a better method name
    static public <T2> Class<MyClass<T2>> of(Class<T2> tClass)
    {
        return (Class<MyClass<T2>>)(Class<?>)(MyClass.class);
    }
}

MyClass<String> result = doit(MyClass.of(String.class)); // no warning

在确保演员阵容安全之后,我们可以单独对该方法施加警告。任何呼叫站点都不会看到警告。

这是所有编译时铸造游戏。在运行时,所有类型参数都被擦除,并且实际上只传递裸类对象。 of方法很可能会被优化掉,所以对于JVM来说,最后一行只是

MyClass result = doit(MyClass.class)

有时候,在运行时,我们需要一个完整的MyClass<String>类型。需要获取ParameterizedType个对象来表示MyClass<String>

当两个需求组合在一起时,也就是说,我们需要一个关于MyClassString的编译时表达式,它将在运行时评估为ParameterizedType

ParameterizedType type_MyClass_String = ???? MyClass ?? String ???

有一种涉及MyClass<String>

的匿名子类的技术
ParameterizedType type_MyClass_String = superTypeOf( new MyClass<String>(){} );

我觉得很令人不安。

答案 2 :(得分:2)

请参阅http://jackson.codehaus.org/1.7.0/javadoc/org/codehaus/jackson/type/TypeReference.html及其引用的参考资料,以全面讨论有关泛型的问题。

底线是,如果您真的想以这种方式使用泛型类型,则必须停止使用Class并开始使用Type及其子类。

与您对其他答案的评论相反,您可以撰写List<List<String>> obj = (List<List<String>>) doit(List.class);,但在撰写时无法避免发出警告。

答案 3 :(得分:1)

自您更新后,您的问题似乎不是一个确切的duplicate

您需要在getClass()的实例上调用MyClass。最好在某处有一个虚拟静态最终实例:

public static final MyClass INSTANCE = new MyClass();
...
return (Class<MyClass<String>>) instance.getClass();

答案 4 :(得分:0)

T对应List,因此String作为List的通用参数的任何引用都无关紧要。

答案 5 :(得分:-1)

  

如何做MyClass<String>.class in   爪哇?

你不能。

Java中的泛型使用类型擦除;参数化参数的类型在编译期间强制执行,但在编译后丢失。生成的泛型类实例的字节代码不包含任何关于其参数的运行时元数据。

就像现在一样,这是不可能的,一个主要的语言设计错误的IMO。