2010-01-06 185 views
18

無界通配符(例如, <?>和有界通配符,其界限是Object,例如, <? extends Object>Java中的無界通配符

我記得有些地方在泛型的早期草案中有所不同,但找不到這個源代碼。

回答

18

作爲pedntry的一個點,是有區別的,如果類/接口/構造/方法聲明瞭一個邊界(比extends Object其他)。

interface Donkey<T extends Thing> { } 

... 
    Donkey<? extends Object> foo; // FAIL 
+0

哇!完全錯過了。 – notnoop 2010-01-07 01:05:42

+0

Hawtin == smrt。 – orbfish 2011-11-08 19:08:45

+2

該示例在javac中編譯7 – irreputable 2013-01-15 22:09:06

-1

java中的所有東西都與基元的擴展對象不同,所以不會有任何區別。 Autoboxing允許使用原語,因此可以說Java中的所有東西都是一個對象。

4

從實驗看來,例如,List<?>List<? extends Object>兩種方式都是分配兼容的,而使用其中一個方式簽名的方法可以使用另一種簽名覆蓋。例如,

import java.util.List; 

class WildcardTest<T> { 
    public void foo(List<? extends T> bar) {} 
} 

class WildcardTest2 extends WildcardTest<Object> { 
    @Override 
    public void foo(List<?> bar) {super.foo(bar);} 
} 
-1

<? extends Object>是完全一樣<?>。對不起,我沒有參考資料,但是...是的。 :)

編輯:當然,我只是從特定的角度思考,當我說。忽略我的答案(這是非常正確的downvoted),並看到真實的故事更高評分的答案。

+0

嘿凱文,很好的碰到你。感謝您查看Executors2的東西,非常感謝。 :-)另外,請隨時查看我修改過的「非常普通的謎題」;我很想看看「官方」答案是什麼,以及我的方法是否被認爲是「作弊」。 :-P – 2010-01-06 22:21:22

+0

哦,我不能,因爲顯然我的帖子被刪除了。 – 2010-02-01 17:22:41

32

從大多數人的實際情況來看,<? extends Object><?>相同,就像大家在這裏所建議的一樣。

然而,他們兩個非常小的和微妙的點不同:

  1. 的JVMS(Java虛擬機規範)具有無界通配符特殊規格,爲ClassFileFormat-Java5規定,無界通配符編碼爲*同時將對象限制通配符編碼爲+Ljava/lang/Object;。這種改變會通過分析字節碼的任何庫泄漏。編譯器編寫者也需要處理這個問題。從revisions to "The class File Format"

  2. 從reifiablity的角度來看,這些是不同的。 JLS 4.6 and 4.7 codify List<?>作爲一種可修飾類型,但List<? extends Object>作爲一種刪除類型。任何添加.isReifiable()(例如mjc lib)的庫編寫者都需要考慮這一點,以遵守JLS術語。從JLS 4.6 and 4.7

+1

+1,謝謝!不知道! :) – missingfaktor 2010-01-07 03:39:40

2

很複雜......

對於任何類型的變量T,規範說http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4

每一個類型的變量...有一個約束。如果沒有爲類型變量聲明綁定,則假定爲Object。

人們會認爲它通配符是真的太強了,?應該只是爲? extends Object的簡寫。

但是通過規範搜索,沒有證據表明通配符必須有上限(或下限)。 「無界的」?一致對待有界通配符。

我們可以從子類型規則推斷,即List<?>List<? extends Object>是相互的,即亞型,它們是基本上同一類型。

但是規範將它們分開處理。例如http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7List<?>是reifiable類型,但List<? extends Object>不是,這意味着

// ok 
    List<?>[] xx = {}; 
    // fail 
    List<? extends Object>[] yy = {}; 

    // ok 
    boolean b1 = (y instanceof List<?>); 
    // fail 
    boolean b2 = (y instanceof List<? extends Object>); 

我不明白爲什麼,但。說通配符必須有一個上限和一個下限似乎很不錯,默認爲Objectnull type

+0

[JLS8](http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.5.1) - 通配符? extends Object相當於無界通配符? – ZhongYu 2015-06-13 18:06:47

+0

javac8 - 允許'List <?擴展Object> []',但不是'instanceofList <?擴展Object>' – ZhongYu 2015-06-13 18:07:24