[英]Why this piece of java code with generics doesn't compile
Test.java:
import java.util.ArrayList;
import java.util.Stack;
import java.util.Iterator;
class Wrapper<T> {
public T content;
public ArrayList<Wrapper> children;
}
public class Test {
public static void testing (Stack<Wrapper> stack) {
Wrapper test = stack.pop();
Iterator<Wrapper> itr = test.children.iterator();
while (itr.hasNext()) {
Wrapper item = itr.next();
System.out.println(item.content);
}
ArrayList<Wrapper> canCompile = test.children;
for (Wrapper child : canCompile) {
System.out.println(child.content);
}
for (Wrapper child : test.children) {
System.out.println(child.content);
}
}
}
錯誤:
Test.java:25: error: incompatible types
for (Wrapper child : test.children) {
^
required: Wrapper
found: Object
Note: Test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
我的問題不是如何使這個代碼工作。 但是為什么這個代碼不能編譯。 上面的代碼以非正統的方式使用泛型,並且它還產生編譯警告。 但是我仍然期望編譯器有足夠的信息來編譯上面的代碼。
你聲明了
Wrapper test = stack.pop();
您正在使用Wrapper
作為原始類型 。 因此,在編譯時,具有通用組件的所有方法和字段都顯示為其擦除。
所以
public ArrayList<Wrapper> children;
出現為
public ArrayList children;
ArrayList
的iterator()
方法聲明為
public Iterator<E> iterator() {
其中E
是ArrayList
的類型參數。 它的擦除變成了
public Iterator iterator() {
Iterator#next()
方法聲明為
E next();
所以它的擦除反過來變成了
Object next();
您隱式(通過for-each循環)嘗試將Object
類型的值分配給Wrapper
類型的引用。
你沒有輸入你的Wrapper
,
public static void testing (Stack<Wrapper> stack) // <-- Here
要么
Wrapper test = stack.pop(); // <-- or here.
而且,這就是為什么這不是通用的。 你應該有Wrapper<TYPE>
,其中TYPE
是合適的。
但是我仍然期望編譯器有足夠的信息來編譯上面的代碼。
不,不。 因為你沒有給編譯器足夠的信息。
您在代碼中使用原始類型Wrapper
,在這種情況下,編譯器無法使用所有泛型類型信息。 因此,編譯器將ArrayList<Wrapper>
看作只是ArrayList
,這就是為什么當你迭代它時,你會得到Object
類型值而不是Wrapper
類型。
有關更多詳細信息,請參閱JLS§4.8 - 原始類型 :
未從其超類或超接口繼承的原始類型C的構造函數(第8.8節),實例方法(第8.4節,第9.4節)或非靜態字段(第8.3節)M的類型是對應的原始類型在對應於C的通用聲明中擦除其類型
另見:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.