I have a group of classes that all implement a validation interface which has the method isValid()
. I want to put a group of objects--all of different classes--into an ArrayList, loop through them and call isValid()
on each.
Here's my code
Email email = new email();
Address address = new Address();
ArrayList<? extends Validation> myValidationObjects = new ArrayList();
But when I try to do:
myValidationObjects.add(email);
I get:
The method add(capture#2-of ? extends Validation) in the type ArrayList is not applicable for the arguments (Email)
Both Email
and Address
implement Validation.
According to this document , I should be able to use extends
for both interfaces and subclasses.
You can use:
List<Validation> myValidationObjects = new ArrayList<>(); // Java 7
List<Validation> myValidationObjects = new ArrayList<Validation>(); // pre Java 7
Now you can add any instance of a class that implements Validation
to that list.
List<? extends Validation> myValidationObjects
" myValidationObjects
is list of objects that extend Validation
."
" myValidationObjects
can be a list of any type that extends Validation
. For example, it could be a List<RangeValidation>
or a List<RegexValidation>
."
Since there is no object you can legitimately add to both a List<RangeValidation>
and a List<RegexValidation>
, Java prevents you to call add
on a variable of such type.
Your case is in fact the simpler one: you need the definite type List<Validation>
.
The declaration ArrayList<? extends Validation>
ArrayList<? extends Validation>
means a list of an unknown class that extends Validation
. Email
is not compatible with this unknown class.
You can use ArrayList<Validation>
for your list.
If a generic class's T
is <? extends Foo>
<? extends Foo>
, then the only thing you can pass to a method that takes T
is null
-- not any subclass that extends Foo
.
The reason is that List<? extends Validation>
List<? extends Validation>
doesn't mean "a list of things that extend Validation". You can get that with just List<Validation>
. Instead, it means "a list of some type, such that that type extends Validation."
It's a subtle distinction, but basically the idea is that List<? extends T>
List<? extends T>
is a subtype of List<T>
, and you therefore don't want to be able to insert anything into it. Think of this case:
List<FooValidation> foos = new ArrayList<>();
List<? extends Validation> validations = foos; // this is allowed
validations.add(new BarValidation()); // not allowed! this is your question
FooValidation foo = foos.get(0);
If the third line were allowed, then the last line would throw a ClassCastException.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.