0

I have one doubt on generics implementation on below code,

class A {

    public void print(List obj) {
    }

    public static void main(String args[]) {
        ClassA aObj = new ClassA();
        List<String> strList = new ArrayList<String>();
        strList.add("ABC");
        aObj.print(strList); // Complile time error
    }
}

Why I am getting complie time error. I know, to avoid the type casting or runtime ClassCastException, jdk 1.5 introduces generics but in above piece of code, I simply thought of parent-child concept and tried to pass List of String instead of Object. Then why I am getting the compile time error.

Justification Of my question Let's suppose, if I write the same above piece of code like,

class A {

    public void print(Object obj) {
    }

    public static void main(String args[]) {
        ClassA aObj = new ClassA();
        aObj.print("ABC"); // Vallid
    }
}

Its Works!!

Please help me to get out of here. Thanks.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
Manish
  • 33
  • 2
  • When posting blocks of code you must indent them by four spaces, with a blank line before and after, in order to get them to show up as verbatim preformatted text instead of being interpreted as html. This is particularly relevant for generics questions as you lose all the `<...>` stuff otherwise. – Ian Roberts Sep 25 '14 at 09:13
  • 1
    Are you sure, you're using `List` and not `List`? By the way, if you want your method to accept all the lists you should make it accept `List>` to compile without warnings. – Dmitry Ginzburg Sep 25 '14 at 09:20
  • The code and the text do not seem to match, but it's most likely a duplicate of http://stackoverflow.com/questions/22144671/why-liststring-is-not-acceptable-as-listobject (which in turn is a duplicate of http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p )) – Marco13 Sep 25 '14 at 09:56

2 Answers2

0

Simply because a List<String> is not a type of List<Object>. This is the typical trap with generics when you start learning it. At first, you may think intuitively that a list of Strings is in fact a list of Objects, since Strings are Objects, right? However, automatic casting from List<String> to List<object> would allow the receiver of the List<Object>-argument to pass in (add) arbitrary Objects to your List of Strings, which is precisely what you are trying to prevent with Generics:

List<String> strings = new List<String>();
strings.Add("a");
strings.Add("b");

// Not allowed, but for illustration.
List<Object> objects = strings;
objects.Add(new Object()); // Oops!
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
Wim.van.Gool
  • 1,290
  • 1
  • 10
  • 19
  • 2
    OP used a `List`, not `List`, so there should be warning (of using non-generic types), not error. For example, this compiles: http://pastebin.com/rTKCTxPc – Dmitry Ginzburg Sep 25 '14 at 09:15
  • This should actually most certainly be an error, since you can provide a check that the type that is passed is incorrect. Putting it as a warning will make for a lot of potential bugs. (since programmers are lazy by definition) – Kurt Du Bois Sep 25 '14 at 09:18
  • @KurtDuBois I'm not talking about how it should be (but you should this about backward compatibility here), but about how it is. – Dmitry Ginzburg Sep 25 '14 at 09:19
0

List<String> is not a type of List<Object>.

If you define print to call toString on every List item, you can do something like this:

public void print(List<?> obj) {
    for(Object o: obj)
         obj.toString();
}

In this case, List will contain "some" objects of a given unknown type (at compile time). Since toString() is a method defined in Object, you will not get any compile-time error. Consider investigating the Java Generic Wildcards

However, if your print code is like the one you posted, you should just get a warning. If the signature is print(List<Object> obj), then you have a compile error for the reason I mentioned.

Manu
  • 4,019
  • 8
  • 50
  • 94