[英]What does <E> mean in Collection<E>?
代碼Collection<E>
上的<E>
含義是什么?
這意味着您正在處理類型為E
的項目集合。 想象一下,你喝了一杯茶。 它也可以裝咖啡,而不是茶,所以將杯子描述為通用實體是有意義的:
class Cup<T> { … }
現在你可以用咖啡或茶(或其他東西)填充它:
Cup<Tea> cuppa = new Cup<Tea>();
Cup<Coffee> foamee = new Cup<Coffee>();
為了實現這一點, Tea
和Coffee
都需要是程序中定義的類型。
這是對代碼的編譯時約束 。 從(相當無用的)杯子示例回來,集合(數組,列表......)通常包含一種類型的項目,例如整數或字符串。 泛型幫助您在Java中表達這一點:
Collection<String> strList = new ArrayList<String>();
strList.add("Foobar"); // Works.
strList.add(42); // Compile error!
注意上面的編譯錯誤? 你只有在使用泛型時才會得到這個。 以下代碼也有效,但不會給出錯誤消息:
Collection strList = new ArrayList();
strList.add("Foobar"); // Works.
strList.add(42); // Works now. Do we really want this?!
這是泛型的使用。 檢查此介紹 。 然后不要忘記閱讀本教程 。
摘錄如下(比較演員與使用仿制品的比較):
當您看到代碼<Type>時,請將其讀作“Type”; 上面的聲明讀作“字符串集合c。”使用泛型的代碼更清晰,更安全。 我們已經消除了一個不安全的演員陣容和一些額外的括號。 更重要的是,我們已將方法的部分規范從注釋移動到其簽名,因此編譯器可以在編譯時驗證在運行時不違反類型約束。 因為程序在沒有警告的情況下編譯,我們可以肯定地說它不會在運行時拋出ClassCastException。 使用泛型的凈效果,特別是在大型程序中,是提高了可讀性和穩健性。
例如,List的接口是
public interface List<E> {
void add(E x);
Iterator<E> iterator();
}
這意味着您可以構建一個列表,其內容都是相同的顯式類型(不僅是Object類型),即使您自己定義了類型。 因此,如果您創建一個Name類,您可以編寫
List<Name> nameList = new ArrayList<>();
然后用Name實例填充它並直接從它中檢索Name實例,而不必拋出或以其他方式擔心它,因為你總是得到一個Name實例或null返回,而不是一個不同類型的實例。
更重要的是,您不能在這樣的List中插入與Name實例不同的任何內容,因為它在編譯時會失敗。
nameList.add(false); //Fails!
nameList.add(new Name("John","Smith")); //Succeeds supposing Name has a
//firstName, lastName constructor
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.