幾年前,當Java7已經發布了一年左右時,我已經從C#開始回到Java - 在某些方面,Java通用對我來說似乎很奇怪。'Java操作符'缺少Java中變量的定義嗎?
有一個我回來了一遍又一遍,這兩個答案的普及看到...
- Difference between <? super T> and <? extends T> in Java
- What is PECS (Producer Extends Consumer Super)?
...看來很多人們(包括我)「自然地」會期望與「泛型集合」聲明中的語法不同的行爲。考慮下面的代碼示例...
注:建築正確性超出範圍 - 假設baseClassesStorage
應該可用於都得到/添加在外界
public class DummyClass {
public static class BaseClass {}
public static interface ListOfAtLeastBaseClasses<T extends BaseClass> extends List<T> {}
public ListOfAtLeastBaseClasses<?> baseClassesStorage;
public void addToStorage(BaseClass item) {
baseClassesStorage.add(item);
}
}
...典型的程序員從非Java世界將假設ListOfAtLeastBaseClasses<?> baseClassesStorage
說:「這是從BaseClass
衍生物品存儲」,但這個樣本的編譯在baseClassesStorage.add(item)
失敗,以下錯誤:
C:\Temp\...\DummyClass.java:14: error: no suitable method found for add(BaseClass)
baseClassesStorage.add(item);
^
method Collection.add(CAP#1) is not applicable
(argument mismatch; BaseClass cannot be converted to CAP#1)
method List.add(CAP#1) is not applicable
(argument mismatch; BaseClass cannot be converted to CAP#1)
where CAP#1 is a fresh type-variable:
CAP#1 extends BaseClass from capture of ?
這種行爲的原因在兩個above mentioned answers
中描述。
但是,我應該怎麼做才能實現我的用例以'正確'和'優雅'的方式?
選項我知道有關:
看來,「正確的Java方法」的聲明變量
public ListOfAtLeastBaseClasses<BaseClass> baseClassesStorage;
但這樣一來我確實有下界是「名單的冗餘定義' - 它已經在ListOfAtLeastBaseClasses類的'合同'中定義。這裏的另一個問題 - 如果在某個時間點,我想要改變ListOfAtLeastBaseClasses類的下限,那麼我將需要遍歷所有這種類型的成員變量並改變它們的定義:(。使用'raw 「類型
public ListOfAtLeastBaseClasses baseClassesStorage;
這將編譯,但有效去除類型檢查和編譯過程中產生不必要的警告。...還有什麼是可能的?...
ListOfAtLeastBaseClasses<?> baseClassesStorage;
- 是Java 不同的事情
ListOfAtLeastBaseClasses<> baseClassesStorage;
- 編譯出錯ListOfAtLeastBaseClasses<*> baseClassesStorage;
- 編譯出錯
你能告訴我更多關於'不必要的複雜性'的含義嗎?我問的是因爲對於我聲明數百個變量爲「ListOfAtLeastBaseClasses」比「ListOfAtLeastBaseClasses <*>」或「ListOfAtLeastBaseClasses <>」更復雜。不久之後 - 當前的鑽石操作員在創建實例時刪除類型定義冗餘。我認爲同樣消除'定義變量'的冗餘會降低代碼的複雜性。 –
泛型類型的大多數用法在於使用比上限更具體的類型(否則在首先將類型設置爲泛型的時候沒有多少意義)。例如:我不記得上次我使用List
更不用說您的提議會使代碼不易讀。要知道Foo中的實際類型foo <*> foo = someMethod()'我必須查看Foo的類型定義才能知道上限是什麼。 –