Java泛型:Set vs. Set <object> </object>

时间:2011-07-18 17:57:24

标签: java generics casting

在Java中,声明变量SetSet<Object>之间的区别是什么?这两者不应该相同吗?如果将Set<Object>变量分配给Set,为什么会出现编译时错误?

5 个答案:

答案 0 :(得分:3)

这不是编译时错误。这只是一个警告。这个编译很好:

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

顺便说一下,

也是如此
so = s;

从使用角度来看,它们基本相同。

答案 1 :(得分: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作为函数的参数。您可以使用extends

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

在这种情况下,SetSet<Object>Set<String>都可以传入函数,即使它们都不同。

答案 2 :(得分:1)

否:Set<>是通用的,而Set则不是。逻辑上,Set<Object>可能等同于Set(隐式地,Set of Object),但字节码完全不同:)

建议:

在示例程序上运行javap命令并自行验证。

答案 3 :(得分:1)

它是Java 1.4及以下版本与1.5及以上版本之间的区别。

有很多关于原因的信息。

http://download.oracle.com/javase/1,5.0/docs/guide/language/generics.html

答案 4 :(得分:0)

这两者并不相同。当您指定Set<Object>时,您可以增加编译器检测不安全操作的能力,否则会在运行时失败。

Josh Bloch的优秀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);
}