[英]Accepting subtypes in generic sets
我試圖找到一種方法來返回通用集,該通用集將接受子類型。 下面的代碼返回Set<? extends A>
Set<? extends A>
到我要添加B
。
import java.util.Set;
import java.util.HashSet;
public class Test {
private static class A {}
private static class B extends A {}
public Set<? extends A> getSet() {
return new HashSet<B>();
}
public void work() {
getSet().add(new B()); // compile error
}
}
導致以下錯誤:
Test.java:13: cannot find symbol
symbol : method add(Test.B)
location: interface java.util.Set<capture#320 of ? extends Test.A>
getSet().add(new B());
通用通配符教程指出不能將B
添加到Set<? extends A>
Set<? extends A>
因為我們不知道B
是否是A
的子類型,但是我只是這樣定義它。 有人可以幫我澄清一下嗎?
從根本上講這是不可能的。
如果該方法實際上返回HashSet<C>
怎么辦?
您剛剛將B
添加到C
的集合中。
檢查類型安全性時,將忽略方法的內容( return
語句)。
如果要執行此操作,則應只返回一個普通的HashSet<A>
。
問題的實質是,您可以以這種方式使用通配符來遍歷擴展公共父對象並執行讀取操作的不同對象,但是如果您要寫入集合,則該操作將無效。
原因是編譯器無法確定將從getSet()方法返回的集合的運行時類型。 它不會解析您編寫的代碼並嘗試做出該決定。
通用通配符教程指出不能將B添加到Set <? 擴展了A>,因為我們不知道B是否是A的子類型,但是我只是這樣定義它。
那不是很正確。 說B和C分別擴展a。 getSet()方法可能返回一組B或一組C。您不知道。 因此,您不能僅在其中添加B。 可能是一組C,這將破壞合同。
問題不在於您是否不知道B是A的子類型,而是您不知道A的子類型? 是。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.