使用泛型,类<! - ? - >类型解析IDE警告

时间:2009-05-31 16:34:16

标签: java generics class

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,专门用于“类”对象。

5 个答案:

答案 0 :(得分:2)

ClassClass<?>并非完全等同于。它们是语义等价的,但后者有效地告诉编译器,“是的,我知道这是一个泛型类型,但我对类型参数一无所知。”前者只是原始类型,通常可以表示它是旧代码,但尚未迁移到使用泛型。

这在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中看到了这种行为。