2011-07-18 42 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>可以在所有的功能被传递,虽然他们都是不同的。