在Java中,声明变量Set
与Set<Object>
之间的区别是什么?这两者不应该相同吗?如果将Set<Object>
变量分配给Set
,为什么会出现编译时错误?
答案 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) {}
在这种情况下,Set
,Set<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);
}