以下代码有注释,表示两条相似的行,其中一条编译,其中一条不行。是通过设计还是忽略了Java的常量特定类体的非泛型getClass()方法?
public class TestGenericCollections extends TestCase {
List<Key<? extends Enum<?>>> keyList;
public TestGenericCollections() {
keyList = Lists.newArrayList();
}
public <T extends Enum<T>> void addEnum(List<T> values) {
Preconditions.checkArgument(values.size() > 0);
// Signature of Key.get():
// public static <T> Key<T> get(Class<T> type)
// the following line compiles without warning or error
keyList.add(Key.get(values.get(0).getDeclaringClass()));
// The following line fails to compile with this error message in Eclipse:
// The method add(Key<? extends Enum<?>>) in the type List<Key<? extends Enum<?>>>
// is not applicable for the arguments (Key<capture#1-of ? extends Enum>)
keyList.add(Key.get(values.get(0).getClass()));
}
错误信息非常有趣。请注意,没有Enum<?>
,这是生的Enum
。这意味着任何泛型方法/集合/等。如果想要避免编译器警告,那么想要在匿名常量类体上操作的枚举类型必须放弃泛型并使用注释@SuppressWarnings(“rawtypes”)。这就是为什么这行不会编译,但它会超过它。 Enum<T>.GetDeclaringClass()
正确地返回一个泛型类型,但编译器创建的每个Enum
值不变的匿名常量特定类不会。
那么,基本原理是什么?这是一种疏忽吗?或者说是语言设计者没有改变Enum
的Enum
的getClass()
方法的匿名常量特定类体上的签名是否类似于他们在将Java泛型添加到语言时所做的那样?
什么类是'Key'? – Bohemian 2012-01-06 06:41:55
这是Guice的一部分,但这对于这个目的无关紧要。您可以将集合类型想象为List >>,你会得到相同的结果。 –
2012-01-06 06:52:08