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
?
Worth noting, you can also create the list of your superClass from a list of subClass as such:
myMethod(new ArrayList<SuperClass>(list));
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.
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