Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why List<String> is not acceptable as List<Object>? [duplicate]

Consider below method doSomething(List<Object>) which accepts List<Object> as parameter.

private void doSomething(List<Object> list) {
    // do something
}

Now consider below code snippet which tries to call doSomething() where I try to pass List<String> to doSomething()

List<Object> objectList;
List<String> stringList;

doSomething(stringList); // compilation error incompatible types
doSomething(objectList); // works fine 

Even below code throws compilation error

objectList = stringList;  // compilation error incompatible types

My question is why List<String> can not be passed to a method which accepts List<Object>?

like image 840
user3374518 Avatar asked Mar 03 '14 10:03

user3374518


People also ask

Can you pass list String to list object?

Any Collection can be passed as an argument to the constructor as long as its type extends the type of the ArrayList , as String extends Object . The constructor takes a Collection , but List is a subinterface of Collection , so you can just use the List<String> .

Is List String a subtype of List object?

String is a subtype of Object , yes, but that does not mean that List is a subtype of List.

What is the difference between list String and ArrayList String?

The List is an interface, and the ArrayList is a class of Java Collection framework. The List creates a static array, and the ArrayList creates a dynamic array for storing the objects. So the List can not be expanded once it is created but using the ArrayList, we can expand the array when needed.

Is String a subtype of Object?

String is a subtype of Object , because the String class is a subclass of the Object class. int is not a subtype of Object , because none of Java's primitive types are subtypes of any reference type.


3 Answers

Because while String extends Object, List<String> does not extend List<Object>

Update:
In general, if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>.

This is because collections do change. In your case, If List<String> was a subtype of List<Object>, then types other than String can be added to it when the list is referenced using its supertype, as follows:

List<String> stringList = new ArrayList<String>;
List<Object> objectList = stringList;// this does compile only if List<String> where subtypes of List<Object>
objectList.add(new Object());
String s = stringList.get(0);// attempt to assign an Object to a String :O

and the Java compiler has to prevent these cases.

More elaboration on this Java Tutorial page.

like image 60
Ahmad Y. Saleh Avatar answered Oct 18 '22 03:10

Ahmad Y. Saleh


You could put an object of a wrong type into the list IF this worked:

private void doSomething(List<Object> list) {
    list.add(new Integer(123)); // Should be fine, it's an object
}

List<String> stringList = new ArrayList<String>();
doSomething(stringList); // If this worked....
String s = stringList.get(0); // ... you'd receive a ClassCastException here
like image 34
Marco13 Avatar answered Oct 18 '22 03:10

Marco13


This generic question in Java may look confusing to any one who is not very familiar with Generics as in first glance it looks like String is object so List<String> can be used where List<Object> is required but this is not true. It will result in compilation error.

It does make sense if you go one step further because List<Object> can store anything including String, Integer etc but List<String> can only store Strings.

Also have a look at: Why not inherit from List<T>?

like image 11
Shishir Kumar Avatar answered Oct 18 '22 01:10

Shishir Kumar