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

Ali*_*iba 15 java generics

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

编辑:'大卫温斯洛'和'bmargulies'的回答是(MyClass<String>) doit(MyClass.class);原始问题的正确作品,但令人惊讶的是,当方法返回说MyClass<T>而不是T铸造将不再编译.

编辑:我已用MyClass替换了List并将条件添加到我原来的问题中.

Dav*_*low 14

使用List.class.因为类型擦除类型参数的Java类是完全编译时结构-即使List<String>.class是有效的语法,这将是完全一样的类List<Date>.class,等等.由于反射本质上是一个运行时的东西,它不处理好类型参数(在Java中实现).

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

List<String> list = (List<String>)(ArrayList.class.newInstance());
Run Code Online (Sandbox Code Playgroud)


irr*_*ble 6

我已经多次看过类似的问题,例如 获取泛型类类型

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

MyClass<String> result = doit(MyClass<String>.class);
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

MyClass result = doit(MyClass.class)
Run Code Online (Sandbox Code Playgroud)

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

当两个要求结合在一起,那就是,我们需要有关编译时表达式MyClass,并String会在运行时计算为ParameterizedType

ParameterizedType type_MyClass_String = ???? MyClass ?? String ???
Run Code Online (Sandbox Code Playgroud)

有一种涉及匿名子类的技术 MyClass<String>

ParameterizedType type_MyClass_String = superTypeOf( new MyClass<String>(){} );
Run Code Online (Sandbox Code Playgroud)

我觉得很令人不安.