Reputation: 11
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
?
Upvotes: 1
Views: 4678
Reputation: 121799
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.
Upvotes: 1
Reputation: 43590
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);
}
Upvotes: 0
Reputation: 44962
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.
Upvotes: 2
Reputation: 128899
That isn't a compile-time error. It's just a warning. I.e 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.
Upvotes: 3
Reputation: 24910
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
Upvotes: 1