通用构造函数(Class <t> clazz)不支持T,其中T是另一个泛型</t>

时间:2013-01-12 17:56:10

标签: java generics

想象一下这个课程:

public class ObjectCreator<T> {
    private Class<T> persistentClass;

    public ObjectCreator(Class<T> persistentClass) {
        this.persistentClass = persistentClass;
    }

    public T create() {
        T instance = null;
        try {
            instance = persistentClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        } 

        return instance;
    }
}

现在我用域对象对其进行子类化:

public class PersonCreator extends ObjectCreator<Person>{

    /**
     * @param persistentClass
     */
    public PersonCreator() {
        super(Person.class);

    }

}

一切都很棒...... 但是,如果我尝试使用另一个通用域对象将其子类化,编译器会抱怨:

public class MessageCreator extends ObjectCreator<Message<String>>{

    /**
     * @param persistentClass
     */
    public MessageCreator() {
        super(Message.class);
    }

}
  

构造函数ObjectCreator<Message<String>>(Class<Message>)未定义MessageCreator.java

我认为这是一个很大的限制:为什么这是禁止的?

任何想法如何解决?

的Massimo

3 个答案:

答案 0 :(得分:3)

试试这个:

super((Class<Message<String>>) ((Object) Message.class)); //compiles with warning

如果你将基类的构造函数改为

,那就更好了
public ObjectCreator(Class<? extends T> persistentClass)

然后在开源课程中使用它:

super(new Message<String>(){}.getClass()); //compiles without warning

它将在没有警告的情况下编译

修改

根据getClass() http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#getClass()

的定义

返回Class<? extends X>,其中X是调用getClass的表达式的静态类型的擦除。这意味着getClass()将为Class<? extends Message>返回new Message<String>(),为匿名类Class<? extends Message<String>>返回new Message<String>(){}

答案 1 :(得分:1)

泛型类没有'.class'变体 - 信息在运行时不可用,为了使上面的代码编译,你可以简单地将表达式转换为所需的类型。

super ((Class<Message<String>>)((Class<?>)Message.class));

请注意,这不会使信息在运行时可用(即用于反射等),但是它应该使用未经检查的警告进行编译 - 这只是一个警告。

答案 2 :(得分:0)

只要你使用

就可以了
public class MessageCreator extends ObjectCreator<Message>{

    /**
     * @param persistentClass
     */
    public MessageCreator() {
        super(Message.class);
    }

}

这会创建正确的对象,但仍然会给出类定义的警告,如果你这样做了

Message<String> m = creator.create();