开发者

Java generics: Set vs. Set<Object>

开发者 https://www.devze.com 2023-03-21 17:09 出处:网络
In Java, what\'s the differen开发者_JS百科ce 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<

In Java, what's the differen开发者_JS百科ce 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. 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.


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.


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


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.


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);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消