以下代碼有註釋,表示兩條相似的行,其中一條編譯,其中一條不行。是通過設計還是忽略了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