簡體   English   中英

使用對象作為無界通配符引用對象的參數

[英]Using an Object as argument on unbounded wildcard reference object

簡單類:

class Box<T> {
    private T t;

    public Box(T t) {
        this.t = t;
    }

    public void put(T t) {
        this.t = t;
    }
}

試圖執行put()方法傳遞Object的實例

Box<?> box = new Box<String>("abc");
box.put(new Object());

編譯器指出一個錯誤:

The method put(capture#1-of ?) in the type Box<capture#1-of ?> is not applicable for the arguments (Object)

實際上,編譯器不知道期望的類型,但是可以肯定的是-它將是Object或它的子類。 為什么會引發錯誤?

謝謝

您的示例清楚地說明了原因。

框的實際類型為Box<String> 因此,您真的不希望將String實例以外的其他內容放置到此框中。

Box<?>意思是:“一個編譯器不知道的某種類型的盒子”。 因此,您可以從這樣的盒子中獲得所需的任何東西,並且可以獲得Object實例,但是您可能不會在盒子中存儲任何東西,因為編譯器無法保證所存儲的對象具有適當的類型:

class Box<T> {
    private T t;

    public Box(T t) {
        this.t = t;
    }

    public void put(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }
}

Box<?> box = new Box<String>("abc");
Object o = box.get(); // no problem
box.put(new Object()); // fail

泛型的目標是使代碼類型安全。 如果您可以向實際上是Box<String>的盒子中添加任意對象,那么您將不再具有任何類型安全性。

本教程指出:

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Same compile time error as yours

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

另一方面,給定一個List,我們可以調用get()並利用結果。 結果類型是未知類型,但我們始終知道它是一個對象。 因此,可以安全地將get()的結果分配給Object類型的變量,或將其作為參數傳遞給需要Object類型的位置。”

解釋一下,基本上可以調用get()返回類型,但是不能添加,因為編譯器不知道它是什么類型,並且傳遞的參數需要擴展未知類型。

暫無
暫無

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

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