需要根据限定的类名字符串传递Generic Class Type参数

时间:2014-09-05 09:18:42

标签: java generics

仅在运行时我传递了完全限定的类名(即“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无法解析为某种类型”。

我怎样才能做我想要的(逻辑上)。

非常感谢。

4 个答案:

答案 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

您应该坚持使用旧的非类型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

答案 3 :(得分:0)

泛型仅在编译时用于编译时类型检查。因此,如果在编译时不知道类型参数,则它没有用处。