如何public <T> T doit(Class<T> clazz);
使用MyClass<String>.class
clazz作为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)
我已经多次看过类似的问题,例如 获取泛型类类型
构造静态泛型类型有合理的理由.在操作上,他可能会喜欢
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)
我觉得很令人不安.
归档时间: |
|
查看次数: |
18717 次 |
最近记录: |