2014-09-05 77 views
0

只有在运行时我在通过了完整的类名(即“com.firm.me.MyClass”)需要传递一个泛型类的类型参数的基础上,合格的类名称的字符串

我需要实例化一个通用类,定义为:

Class A <T> 
{ 
} 

其中“T”是与传入的全限定类名称关联的类型。

我有以下几点:

Class <?> clazz = Class.forName ("com.firm.me.MyClass"); 

我想(从逻辑上说)有类似的东西..

A <clazz> myInstance = new A <clazz>; 

上面的使用位置“clazz中”的会引起以下错误:

“clazz无法解析为类型”。

我该如何做我想做的事(逻辑上)。

非常感谢。

+0

由于类型擦除'A myInstance'无论如何都会解析为'A myInstance',所以即使你得到了这个工作,你也不会从中受益。你究竟想要做什么? – Thomas 2014-09-05 09:22:18

+0

我有一个序列化的持久数据存储。可能有几家商店,并且每个商店内的所有对象都是相同类型的。我在“A类”上面给出的类例子实例化了我的持久/提取类。我想要做的是让用户输入保存在其数据存储中的数据类型的类名,以便我可以使用通用的基于命令行的应用程序,然后可以使用该应用程序来检索其数据。我想基于它们从命令行 – user1151685 2014-09-05 09:49:29

+0

@ user1151685输入的完全限定类名实例化persist/retriever实例,您应该在类A中声明一个成员变量,并通过构造函数初始化它。让我知道下面的解决方案解决您的问题 – 2014-09-05 10:02:30

回答

4

你不能在Java中做这样的事情。阅读关于类型erasure

除了类型擦除的问题 - 这使得在任何情况下都不可能 - 你根本不能保证T有一个暴露的,无参数的构造函数!

传统的解决方法是传递工厂对象,这些工厂对象提供可用于获取T对象的方法。一个简单的例子是

interface Factory<T> { 
    T create(); 
} 

,然后你的类可以得到一个Factory<T>,并呼吁create()它来获得更多的T's。更复杂的示例可能需要额外的参数,例如create()方法或重载。

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); 
    } 
} 

只要创建一个构造函数,需要一个类object.In这样一来,不仅是你在运行时得到正确的类对象,可以使用泛型以您想要的方式处理参数化对象

0

在Java中,必须在编译时解析泛型类型。事实上,由于着名的类型擦除(请检查:Get generic type of class at runtime),它们在运行时几乎无法访问。

检查大约同样的问题这个问题:Dynamic Generic Typing in Java

你应该坚持旧的非类型AA<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

一些运行时检查
0

泛型是只在编译时用于编译时类型检查。因此,如果在编译时未知类型参数,则不起任何作用。

相关问题