簡體   English   中英

需要幫助以了解有關泛型的Java教程

[英]Need help in understanding Java tutorial on Generics

我正在從這里閱讀Java教程。 我在理解一條簡單的線時遇到了麻煩。

教程說Collections.emptyList聲明是:

static <T> List<T> emptyList();

因此,如果我們編寫List<String> listOne = Collections.emptyList(); ,它的工作方式是Java編譯器能夠推斷出type參數,因為返回的值應為List<String>類型。

現在考慮一個方法: void processStringList(List<String> stringList) 現在它說:

processStringList(Collections.emptyList()); Java SE 7編譯器生成類似於以下內容的錯誤消息:

List <'Object>不能轉換為List <'String>

編譯器需要類型參數T的值,因此它以值Object開頭。 因此,對Collections.emptyList的調用返回類型為List<Object>的值,該值與方法processStringList不兼容。

現在,它們的意思是: 所以它以值Object開頭 我的意思是開始做什么?

基本上,這與編譯器的功能有關。 換句話說:在某種程度上,可能類型推斷的“數量”是一個實現細節。

在Java 7中,有時必須使用類型helper / hints / witnesses,在其中使用Collections.<String>emptyList()來告知編譯器該缺失部分。

以后的編譯器實現改善了您幾乎總是可以使用Collections.emptyList()

關於The compiler requires a value for the type argument T so it starts with the value Object. ……實際上很簡單:java編譯器必須實現一種算法,最后才能推斷出特定類型。 提供一些偽代碼,可能類似於:

Class<?> inferType(SomeSyntaxTree construct) {

我只是在這里使用Class來表示算法將返回類似於已知類型的東西。 現在,該方法可以這樣實現:

 Class<?> inferedType = Object.class
 while (whatever) {
   refine inferedType
 }
 return inferedType

換句話說:當您“搜索”某些值時,這是一種非常常見的方法:使用“最通用”值進行初始化(在Java類型系統中,它將是Object.class),然后查看該通用值可以通過應用任何算法來優化值。

在我們的例子中,優化可能最終會得出“可以使用的最特定類型是String ”的信息,但是如果無法進一步優化,則最終會出現“初始默認值”,即Object

該聲明

processStringList(Collections.emptyList());

在Java 8中工作正常(我也假設在8以上)。 在這種情況下,編譯器足夠聰明,可以通過檢查方法的預期參數類型來推斷類型。

在舊版本中,當編譯器看不到顯式的返回類型時(如List<String> listOne = Collections.emptyList(); ),默認情況下它將<T>推斷為java.lang.Object 但是請注意, List<Object>List<String>不兼容。

您可以將方法聲明為void processString(List<? super String> list)以避免發生錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM