想象一下这个课程:
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
答案 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();