class Test1<T> {
Test1(Class<T> type) {}
}
class Test2 extends Test1<Class> {
Test2() {
super(Class.class);
}
}
这有效,但是,我被警告在“Test1<Class>
”中使用原始泛型类型。我理解,但是,将其更改为“Class<?>
”(应该是等效的?)会在调用super()时出现编译错误 - Class.class显然属于“Class<Class>
”类型而不是“Class<Class<?>>
”。
这些变体似乎都会导致编译错误。
任何人都可以看到如何解决这个问题,这样我总是使用带类的类型参数,因此不会收到IDE警告?这种方式似乎更好,即使它按原样工作。 只要保留基本意图,我就可以对这两个类的结构进行更改:Test2是一种特殊类型的Test1,专门用于“类”对象。
答案 0 :(得分:2)
Class
和Class<?>
并非完全等同于。它们是语义等价的,但后者有效地告诉编译器,“是的,我知道这是一个泛型类型,但我对类型参数一无所知。”前者只是原始类型,通常可以表示它是旧代码,但尚未迁移到使用泛型。
这在Java Generics FAQ中有所介绍 - 请参阅问题“无界通配符参数化类型与原始类型之间有什么区别?”在parameterized types section。
答案 1 :(得分:2)
您的警告源于Class
本身就是参数化类public final class Class<T>
的事实。删除警告的最简单方法是使T
类型参数而不是Class<T>
:
class Test1<T> {
Test1(T type) { Class<?> classType = type.getClass();}
}
class Test2 extends Test1<String> {
Test2() {
super("");
}
}
答案 2 :(得分:1)
我使用Java 1.6.0_14,编译器在编译代码时没有给我任何警告。
答案 3 :(得分:1)
这可能是适合的时间之一:
@SuppressWarnings("unchecked")
class Test2 extends Test1<Class> {
Test2() {
super(Class.class);
}
}
除非您总是使用Test1<Class>
,否则我看不到另一种解决此警告的方法。 (如果你跑javac -Xlint:unchecked
,你可能会得到同样的警告,但我对此并不肯定。)这里的问题是你通常(我假设)正在使用你的班级Test1
ungeneric values,但Class是一个泛化类,它将Class对象作为其参数。我没有看到任何方法,所以我认为最好的解决方案是抑制此特定警告,以便真正的问题突出。
答案 4 :(得分:-1)
简短的回答是无法指定类型参数。这是因为Class对象(例如,List.class,而不仅仅是Class.class)不理解泛型类型参数 - 它在编译期间被擦除。
我的IDE,Intellij IDEA,给出了相同的警告。这是IDE过于激进。您可以使用IDEA来抑制警告(它生成一个@SuppressWarnings注释),但解决它的代码(如Robert Munteau的聪明的解决方法)实际上是引入一些讨厌的设计,以避免IDE消息真的不正确 - JDK会不要将此案视为删除。
编辑:鉴于这一点,我至少应该在这里证明自己的想法。考虑以下事项:
List.class
表示类型为
的类对象 Class<List>
它不能代表一种类型:
Class<List<?>>
因为不知道给定列表是否实际上具有通用参数或它将是什么。 List.class对象必须代表所有类型,只要参数化Class。
JDK不会将此视为不安全操作的证据是,如果您编译代码,则不会向您发出警告。
因此IDE过于敏感。虽然提问者没有指定他使用哪个IDE,但我在Intellij IDEA 8.1.2中看到了这种行为。