簡體   English   中英

較低有界通配符未針對上限有效類型參數進行檢查

[英]Lower bounded wildcard not checked against upper bounded type parameter

我想知道為什么這段代碼編譯成功?

源代碼:

abstract class A<K extends Number>
{
    public abstract <M> A<? super M> useMe(A<? super M> k);
}

編譯成功

它是如何工作的,為什么編譯? M是任何類型,為什么它可以使用? 應該是: <M extends Number> 這不會編譯:

abstract class A<K extends Number>
{
    public abstract <M> A<? super M> useMe(A<M> k);
}

錯誤信息:

類型參數M不在類型變量K的范圍內,其中M,K是類型變量:M extends方法useMe中聲明的Object(A)K extends A類中聲明的Number

有什么不同?

Eclipse錯誤討論了此編譯器行為。 最初,Eclipse編譯器在您的示例中為表達式執行了錯誤,而javac則沒有。 雖然我還沒有直接搜索JLS,但是共識似乎是規范中沒有任何內容要求根據類型參數邊界檢查較低的有界通配符。 在這種情況下,最終由調用者分配一個滿足約束條件的類型(如Stephan Herrmann在該帖子中所推測的那樣)。

這是一段令人驚訝的無意義的代碼。

所有這一切都說A類采用的是泛型K ,它是一個Number並且有一個方法useMe返回A<T> ,對T有一些無意義的額外限制(顯然不是Number )。

這是一個實現,以顯示糖的說法有多少:

abstract class A<K extends Number> {
    public abstract <M> A<? super M> useMe(A<? super M> k);
}

class B extends A<Number> {

    @Override
    public <M> A<? super M> useMe(A<? super M> k) {
        // Not much more you can do here but this.
        return k;
    }

}

? super M ? super M東西只是毫無意義的gobbledegook - 所有編譯器都可以從它派生的是傳遞給它的參數和返回的結果必須是特定未命名類的超類。

泛型可以在編譯時輕松檢測編碼錯誤。 使用像這樣的mumbo-jumbo只是誤導混淆。

<M extends Number>添加到第一個示例不會添加編譯器關心的任何內容。 請記住,如果我們說“M是數字的子類型”和“類型是M的超類型”,你說的是“M的超類型”,我們實際上並沒有說這種類型是否為子類型數。

更好的例子是, MInteger ,變量為A<Object> 雖然顯然不起作用,但它能正確滿足功能的所有要求。

由於無法修復函數定義,它只是讓它通過並假設調用站點將捕獲問題。

您的問題分為兩部分:

第1部分:什么是<M>

方法上存在泛型參數使其成為“類型化方法”,這意味着該方法具有由調用者確定的泛型類型,通常通過推理來確定。 它可能是有界的。 如果類也有類型,並且方法是實例方法,則這兩種類型是不相關的。

第2部分:

泛型類型必須完全匹配。 原因歸結為如果BA的子類型, SomeClass<T extends B>不是SomeClass<T extends A>的子類型,更具體地說, SomeClass<A>不是SomeClass<? super A>的子類型SomeClass<? super A> SomeClass<? super A>

暫無
暫無

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

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