簡體   English   中英

為什么這段帶有泛型的java代碼無法編譯

[英]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;

ArrayListiterator()方法聲明為

public Iterator<E> iterator() {

其中EArrayList的類型參數。 它的擦除變成了

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.

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