import java.util.*;
public class GenericDemo4 {
    public static void main(String r[]) {
        Set s1 = new HashSet();
        s1.add(0);
        s1.add("1");
        dostuff(s1);
    }

    static void dostuff(Set<Number> s) { 
        do2(s);
        Iterator i = s.iterator();
        while(i.hasNext()) System.out.println(i.next() + " ");

        Object [] oa = s.toArray();
        for(int x = 0; x<oa.length; x++)
            System.out.println(oa[x] + " ");
        System.out.println(s.contains(1));
    }

    static void do2(Set s2) { System.out.println(s2.size() + " "); }
}

On line 10 there is a type-safe set as a parameter for the method dostuff and it accepts non generic Set s1. How can it not flag an error for one of it's element being a string(s1.add("1"))? From what I understand, integer 0(s1.add(0)) is accepted since Integer IS-A Number but that's not the case for String so how come no error ? Sorry if it's a silly doubt.

Edited 4 Years Ago by rahul.ch

In your other Thread it seems to me that you don't understand the complete concept of inheritance yet. It would be a good thing to first get to control that.

well, a "1" can be cast to a numerical typ. your original HashSet contains elements of the type Object, not type String, so what happens in that code can look a bit like (and I'm not saying it's exactly this):

Object s = "1";
Integer b = (Integer)s;

Did you try casting a String to an Integer? I thought not! No, you can't cast String to Integer.
You may also notice that the final print (line 18) prints "false".

The real reason for no error is that there's no place where that error will be checked for. The original add of a String is OK because that Set is just, by default <Object>. There's no code that checks that a set passed as a parameter contains only the right kind of data, and nothing you do with the data inside doStuff will fail witha non-Number.

I think this question is drawing your attention to one of (many) "limitations" in the implementation of Generocs.

Yes my knowledge of Inheritance is not much sorry for that but I guess what you both are tyring to tell is that 0 and "1" is treated as Object type and casted to Number? Is that so?

Edited 4 Years Ago by rahul.ch

0 (an int) is auto-boxed into an Integer. "1" is a String and NOT cast to a Number - that's not a valid cast. It just stays as a String.
Note that when you execute (you did execute that code, didn't you?)

System.out.println(s.contains(1));

it is "false", "1" has not been converted to any numeric type.

But James that is what I'm unable to understand, if String "1" is NOT cast to a Number why is it not showing compiler error? The original add part, why there is no error, is because HashSet is not type safe. So no checking done. That I got. But the parameter in dostuff() is type safe to Number so it checks and should give error saying it can't accept a string since String IS-NOT Number unlike Integer. If that is the limitation in Generics you talking about can you re-phrase the limitation or link some article which I can read for such limitation? I read up Kathy Sierra and Bert Bates SCJP and I didn't come across a limitation like that.

Ya I executed it and false had come.

the parameter in dostuff() is type safe to Number so it checks and should give error

Yes, that would be a nice idea, but Java doesn't do that. It does not go through the Set testing each element to see if it a kind of Number every time a Set is passed as a parameter. Presumably that's because it could be a very large overhead. Maybe not a "limitation", but a "design compromise"?

To confirm what is happening, change line 13 to

while(i.hasNext()) System.out.println((Number) i.next() + " ");

then you will get a ClassCastException when it trys to cast the "1" to Number at run time.

Ah! Now it made sense! A design compromise got me stumped :P Anyways thanks a lot guys. I'll now sharpen Inheritance and Generics skills to a better level.

This question has already been answered. Start a new discussion instead.