Manish
Manish

Reputation: 33

Generics: Why passing List<String> instead of List<Object> gives compile time error

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.

Upvotes: 0

Views: 330

Answers (2)

Manu
Manu

Reputation: 4137

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.

Upvotes: 0

Wim.van.Gool
Wim.van.Gool

Reputation: 1330

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!

Upvotes: 0

Related Questions