簡體   English   中英

Java中的泛型,使用通配符

[英]Generics in Java, using wildcards

我有一個關於Java中泛型的問題,即使用通配符。 我有一個像這樣的示例類GenClass:

public class GenClass<E> {

    private E var;

    public void setVar(E x) {
        var = x;
    }

    public E getVar() {
        return var;
    }
}

我有另一個簡單的類:

public class ExampleClass {

}

我寫了以下測試類:

public class TestGenClass {

    public static void main(String[] str) {

        ExampleClass ec = new ExampleClass();

        GenClass<ExampleClass> c = new GenClass<ExampleClass>();

        c.setVar(ec);
        System.out.println(c.getVar());  // OUTPUT: ExampleClass@addbf1
    }

}

現在,如果我使用通配符並在測試類中寫入:

GenClass<?> c = new GenClass<ExampleClass>();

在以下的地方:

GenClass<ExampleClass> c = new GenClass<ExampleClass>();

編譯器對這個新語句沒有任何問題,但它抱怨

c.setVar(ec);

它說“方法(setVar())不適用於參數(ExampleClass)”。 為什么我收到此消息?

我認為我使用通配符的方式使得引用變量c的類型為GenClass,它將接受任何類作為參數 - 在EI的位置上將具有任何類。 這只是變量的聲明。 然后我用它初始化它

new GenClass<ExampleClass>()

這意味着我創建了一個GenClass類型的對象,它具有一個類型為ExampleClass的參數。 所以,我認為現在GenClass中的E將是ExampleClass,我將能夠使用方法setVar(),將其作為類型為ExampleClass的參數。 這是我的假設和理解,但似乎Java不喜歡它,我不對。 任何評論表示贊賞,謝謝。

Java Generics Tutorial中介紹了這種確切的情況。

請注意,[使用通配符],我們仍然可以從[泛型Collection ]中讀取元素並為它們指定類型Object 這總是安全的,因為無論集合的實際類型如何,它都包含對象。 然而,向它添加任意對象是不安全的:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error

由於我們不知道c的元素類型代表什么,我們無法向其添加對象。 add()方法接受類型為E參數,即集合的元素類型。 當實際的類型參數是? ,它代表一些未知的類型。 我們傳遞給add任何參數都必須是這種未知類型的子類型。 因為我們不知道它是什么類型,所以我們無法傳遞任何內容。唯一的例外是null ,它是每種類型的成員。

(強調我的)

mmyers有正確的答案,但我只想評論你的問題的這一部分(這聽起來像你想要使用通配符的理由):

我認為我使用通配符的方式使得引用變量c的類型為GenClass,它將接受任何類作為參數 - 在EI的位置上將具有任何類。 這只是變量的聲明。 然后我用它初始化它

如果你真的想要完成這個,你可以做一些沒有編譯錯誤的事情:

GenClass<Object> gc = new GenClass<Object>();
gc.setVar(new ExampleClass());

但話又說回來,如果你想聲明一個可以包含任何類型的GenClass實例,我不確定你為什么要使用泛型 - 你可以只使用原始類:

GenClass raw = new GenClass();
raw.setVar(new ExampleClass());
raw.setVar("this runs ok");

暫無
暫無

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

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