Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing List<Subclass> to method expecting List<SuperClass>

I have a method that is expecting a List<SuperClass> as argument:

public void myMethod(List<SuperClass> list) {}

I want to call that method with a List<Subclass> something like:

List<SubClass> subList = new ArrayList<>();
// ...
myMethod(subList); // Got an argument mismatch error on this line.

Shouldn't I be able to do this when SubClass extends SuperClass?

like image 909
Derek Avatar asked Feb 16 '12 22:02

Derek


2 Answers

Worth noting, you can also create the list of your superClass from a list of subClass as such:

myMethod(new ArrayList<SuperClass>(list));
like image 81
Brant Avatar answered Nov 15 '22 19:11

Brant


No, generics don't work like that. What you could do is define your method as MyMethod(List<? extends SuperClass> list) (by convention it should be named myMethod(...) btw).

The problem with List<SuperClass> vs. List<SubClass> is that you could add new elements to such lists whereas the compiler wouldn't allow you to add something to a List<? extends SuperClass> - and this has a reason:

Consider the following:

class A {}

class B extends A {}

class C extends A {}

If you now have a List<A> you could add instances of A, B and C. However, if you pass a List<B> to a method as a List<? extends A> parameter, the compiler doesn't know whether it is allowed to add instances of A or C to that list (it wouldn't be allowed, but in case you'd pass a List<A> it would be). Thus the compiler restricts you not to do so.

Defining a parameter as List<A> tells the compiler that is is ok to put instances of all three classes to that list. Now if you would be allowed to pass a List<B> as such a parameter you could end up with a List<B> that contains instances of A and/or C. And this is clearly not what you want and could result in runtime bugs that should be prevented at compile time already - by using generics. That's why your approach doesn't work.

like image 22
Thomas Avatar answered Nov 15 '22 21:11

Thomas