[英]Java ArrayList of ? extends Interface
我有一组类都实现了验证接口,其方法是isValid()
。 我想把一组对象 - 所有不同的类 - 放入一个ArrayList,循环遍历它们并在每个对象上调用isValid()
。
这是我的代码
Email email = new email();
Address address = new Address();
ArrayList<? extends Validation> myValidationObjects = new ArrayList();
但是当我尝试做的时候:
myValidationObjects.add(email);
我明白了:
方法add(捕获#2-of?extends Validation)在ArrayList类型中不适用于参数(Email)
Email
和Address
实现了验证。
根据这个文档 ,我应该能够为接口和子类使用extends
。
您可以使用:
List<Validation> myValidationObjects = new ArrayList<>(); // Java 7
List<Validation> myValidationObjects = new ArrayList<Validation>(); // pre Java 7
现在,您可以将实现Validation
的类的任何实例添加到该列表中。
List<? extends Validation> myValidationObjects
“ myValidationObjects
是扩展Validation
的对象列表。”
“ myValidationObjects
可以是扩展Validation
的任何类型的列表。例如,它可以是List<RangeValidation>
或List<RegexValidation>
。”
由于没有对象可以合法地添加到List<RangeValidation>
和List<RegexValidation>
,因此Java会阻止您List<RegexValidation>
类型的变量调用add
。
你的情况实际上更简单:你需要明确的类型List<Validation>
。
声明ArrayList<? extends Validation>
ArrayList<? extends Validation>
意味着延伸的未知类别的列表Validation
。 Email
与此未知类不兼容。
您可以使用ArrayList<Validation>
作为列表。
如果泛型类的T
是<? extends Foo>
<? extends Foo>
,那么唯一可以传递给T
的方法就是null
- 而不是任何扩展Foo
子类。
原因是List<? extends Validation>
List<? extends Validation>
并不意味着“扩展验证的事项列表”。 只需使用List<Validation>
。 相反,它意味着“某种类型的列表,以便该类型扩展验证。”
这是一个微妙的区别,但基本上这个想法是List<? extends T>
List<? extends T>
是List<T>
的子类型,因此您不希望能够在其中插入任何内容。 想想这个案例:
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);
如果允许第三行,则最后一行将抛出ClassCastException。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.