爲什麼編譯器問題的變量聲明爲編譯器警告
時警告List<? extends Object> list = new LinkedList();
警告:
Note: ZiggyTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
但是,當我變量聲明爲
它不發出警告List<?> list = new LinkedList();
爲什麼編譯器問題的變量聲明爲編譯器警告
時警告List<? extends Object> list = new LinkedList();
警告:
Note: ZiggyTest.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
但是,當我變量聲明爲
它不發出警告List<?> list = new LinkedList();
我無法解釋爲什麼編譯器不會將這些視爲等價的,但假定它不這樣做,我會試着解釋它爲什麼拒絕這麼做。
第一個(List<? extends Object>
)聲稱List
中保存的對象的類型是來自Object
的某種未知類型。第二個(List<?>
)說少;它只是說列表中的對象的類型是未知的。它沒有提及任何預期的超類型作爲未知類型的上界。
爲了驗證第一個假設,編譯器希望聽到您說出在此處構造的List
實例中保留的預期類型,作爲原始類型LinkedList
,該主題沒有提到任何內容。但是,如果要將實例構造爲LinkedList<Object>
類型,則至少要保證對實例的協變讀取與您的斷言保持一致:即,此列表中的內容是某種Object
。
現在,這一切似乎都傻了,因爲Java中的每個參考/非原始類型擴展Object
,所以不應該在List<? extends Object>
和List<?>
之間的理解上發生歧義;畢竟,第二個意味着第一個意義上的,因爲語言的類型系統的授權單根分類階層。
這出現在Java 5和更高版本,如果您使用的集合沒有類型說明符(例如Arraylist()
而不是ArrayList<String>()
)。這意味着編譯器無法使用generics以類型安全的方式檢查您是否正在使用該集合。
要擺脫警告,只需具體說明要在集合中存儲什麼類型的對象。所以,與其
List list = new ArrayList();
應儘可能
List<String> list = new ArrayList<String>();
在你的情況,如果你修改聲明如下,
List<? extends Object> list = new LinkedList<Object>();
將與任何警告,因爲編譯我們現在使用通用類型(<Object>
)來使其類型安全。
結帳http://stackoverflow.com/questions/8683137/and-extends-object/8683314和我的答案中的優秀泛型教程那裏是一個必須閱讀時使用泛型 – Robin 2012-01-01 21:48:01
它不發佈任何減少正如你在NetBeans 6.9.1中用jdk 6所提到的那樣。 – Lion 2012-01-01 22:01:47
我沒有使用IDE。從命令行提示編譯時,是否會收到警告? – ziggy 2012-01-01 22:15:33