仅在运行时我传递了完全限定的类名(即“com.firm.me.MyClass”)
我需要实例化一个Generic类,定义为:
Class A <T>
{
}
其中“T”是与传入的完全限定类名相关联的类型。
我有以下内容:
Class <?> clazz = Class.forName ("com.firm.me.MyClass");
我希望(逻辑上说)有类似的东西。
A <clazz> myInstance = new A <clazz>;
在上述位置使用“clazz”会产生以下错误:
“clazz无法解析为某种类型”。
我怎样才能做我想要的(逻辑上)。
非常感谢。
答案 0 :(得分:4)
你不能用Java做这些事情。阅读有关类型erasure
的信息除了类型擦除的问题 - 这使得在任何情况下都不可能 - 你根本无法保证T
有一个暴露的,无参数的构造函数!
传统的解决方法是传递工厂对象,这些对象提供可用于获取T
对象的方法。一个简单的例子是
interface Factory<T> {
T create();
}
然后您的班级可以获得Factory<T>
并在其上调用create()
以获得更多T's
。更复杂的示例可能需要create()
方法的其他参数,例如,或重载。
答案 1 :(得分:0)
您应该将Class A
更改为以下内容: -
class A<T> {
Class<T> clazz;
public A(Class<T> clazz) {
this.clazz = clazz;
}
public static void main(String[] args) throws ClassNotFoundException {
@SuppressWarnings("unchecked")
Class<com.firm.me.MyClass> clazz = (Class<MyClass>) Class
.forName("com.firm.me.MyClass");
A<MyClass> myInstance = new A<MyClass>(clazz);
}
}
只需创建一个带有Class对象的构造函数。这样,您不仅可以在运行时获取正确的Class对象,还可以使用泛型来按照您的方式处理参数化对象
答案 2 :(得分:0)
在Java中,必须在编译时解析泛型类型。事实上,由于着名的类型擦除,它们在运行时几乎无法访问(请查看:Get generic type of class at runtime)。
检查有关同一问题的问题:Dynamic Generic Typing in Java
您应该坚持使用旧的非类型A
或A<Object>
,您可能会在其中包含一些运行时检查,例如
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#cast%28java.lang.Object%29
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#isAssignableFrom%28java.lang.Class%29
答案 3 :(得分:0)
泛型仅在编译时用于编译时类型检查。因此,如果在编译时不知道类型参数,则它没有用处。