2011-07-18 40 views
1

在Java中,聲明變量a SetSet<Object>之間有什麼區別?兩者不應該相等嗎?爲Set指定Set<Object>變量時爲什麼會出現編譯時錯誤?Java泛型:集與集<Object>

+0

你應該也許可以解決你的問題 – marc

回答

1

編號:Set<>是通用名稱,Set不是。從邏輯上講,Set<Object>可能相當於Set(隱式,Set of Object),但字節碼是完全不同的:)

建議:

運行在你的示例程序javap命令並驗證自己這一點。

3

這不是一個編譯時錯誤。這只是一個警告。即該編譯罰款:

Set s = new HashSet(); 
Set<Object> so = new HashSet<Object>(); 
s = so; 

順便一提,所以不會

so = s; 

而且他們基本上都是從使用的角度相同。

0

這兩者不等價。當您指定Set<Object>時,您可以提高編譯器檢測集合的不安全操作的能力,否則這些操作在運行時會失敗。

這是覆蓋在喬希布洛赫的優秀Effective Java, Second Edition,從這個例子是無恥的啓發:

public static void main(String[] args) { 
    List<String> typesafeStrings = new ArrayList<String>(); 
    unsafeAdd(typesafeStrings, new Integer(0)); // can add a Integer to a List<String>! 
    String s = typesafeStrings.get(0); // fails at runtime, not safe 

    typesafeStrings = new ArrayList<String>(); 
    safeAdd(typesafeStrings, new Integer(0)); // compiler error, safe! 
    s = typesafeStrings.get(0); 

} 

static void unsafeAdd(List list, Object o) { 
    list.add(o); 
} 

static void safeAdd(List<Object> list, Object o) { 
    list.add(o); 
} 
2

這裏就是不等價...

Set<String> s_str = new HashSet<String>(); 
Set s_plain = s_str; // This is valid, although you will get a compiler warning 

// This is invalid, the Set<String> cannot be implicitly cast to object even though 
// it's *contents* are all objects. 
Set<Object> s_obj = s_str; 

現在讓我們假設你想必須將一個通用Set作爲參數傳遞給一個函數。您可以使用擴展

function void foo(Set<? extends Object> s) {} 

在這種情況下,一個Set,一個Set<Object>Set<String>可以在所有的功能被傳遞,雖然他們都是不同的。