[英]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.