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?
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 namedmyMethod(...)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 aList<? extends SuperClass>– and this has a reason:Consider the following:
If you now have a
List<A>you could add instances ofA,BandC. However, if you pass aList<B>to a method as aList<? extends A>parameter, the compiler doesn’t know whether it is allowed to add instances ofAorCto that list (it wouldn’t be allowed, but in case you’d pass aList<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 aList<B>as such a parameter you could end up with aList<B>that contains instances ofAand/orC. 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.