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>
?
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> .
String is a subtype of Object , yes, but that does not mean that List is a subtype of List.
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.
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.
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.
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
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>?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With