In Java, what's the difference between declaring a variable a Set
versus a Set<Object>
? Shouldn't the two be equivalent? Why is there a compile-time error when one assigns a Set<Object>
variable to a Set
?
That isn't a compile-time error. It's just a warning. Ie this compiles fine:
Set s = new HashSet();
Set<Object> so = new HashSet<Object>();
s = so;
And incidentally, so does
so = s;
And they are basically the same from a usage perspective.
Here is where the are not equivalent...
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;
Now let's say you wanted to have to take a generic Set for example as an argument to a function. You can use extends
function void foo(Set<? extends Object> s) {}
In this case, a Set
, a Set<Object>
and a Set<String>
could all be passed in to the function, even though they are all different.
No: Set<>
is generic, and Set
isn't. Logically, Set<Object>
might be equivalent to Set
(implicitly, Set of Object
), but the bytecode is quite different:)
Suggestion:
Run javap
command on your sample program and verify this for yourself.
Its the difference between Java 1.4 and below and 1.5 and above.
There's plenty of information out there on why.
http://download.oracle.com/javase/1,5.0/docs/guide/language/generics.html
The two are not equivalent. When you assign a Set<Object>
you increase the compilers' ability to detect unsafe manipulation of the set that would otherwise fail at runtime.
This is covered in Josh Bloch's excellent Effective Java, Second Edition , from which this example is unashamedly inspired:
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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.