所以,我有以下两个类:
Class A { }
Class B extends A { }
Class C extends A { }
还有下面的方法:
public void foo(Collection<A> bar) {
List<A> listA = new ArrayList<>();
for(A a : bar) {
//a and anotherA are both of the same subtype of A
A anotherA = getAnotherA(a);
listA.add(anotherA);
}
bar.clear();
bar.addAll(listA);
}
现在,我试图以两种不同的方式调用此方法,但我无法让转换正常工作...希望我只是忽略了一些小问题。
所以,这是我调用它的两种方式:
方式一:
A obj = ...;
Field field = //get field representing a collection of sub-type of A
Collection<A> collection = field.get(...);
foo(collection);
方式二:
B obj = ...;
Set<C> setOfC = b.getSetOfC();
foo(setOfC);
我尝试了无数次转换尝试,但我似乎无法编译它!例如,在方式 2 中,我尝试转换 setOfC
至 Set<A>
,但我得到了一个类转换异常。我试过投 bar
至 Collection<? extends A>
,但是 bar.addAll(..) 失败了。我试图向 foo 添加一个泛型,但也出现错误。在方式 1 中,我也尝试过投 collection
至 Collection<? extends A>
, 但还是不走运。
最佳答案
您不能传递 Set<C>
进入一个期待 Collection<A>
的方法,即使是 Set
是 Collection
, 即使是 C
是一个 A
,因为 Java 的泛型是不变的。
您可以在 foo
上引入类型参数方法,带有 A
上限。然后你可以在整个方法中使用类型参数。这将确保 A
的相同子类型被使用。
public static <T extends A> void foo(Collection<T> bar) {
List<T> listA = new ArrayList<>();
for(T a : bar) {
//a and anotherA are both of the same subtype of A
T anotherA = getAnotherA(a);
listA.add(anotherA);
}
bar.clear();
bar.addAll(listA);
}
您的评论似乎表明 a
和 anotherA
是同一类型,所以这应该为你编译。如果不是,则 getAnotherA
方法需要一些工作,以便传入 C
将返回 C
而不是 A
.
关于java - Java 中子类和集合之间的类转换异常问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36159205/