我正在尝试编写一个方法,该方法将返回一个集合(例如Arraylist),该集合使用泛型声明为包含父类或扩展父类的类。对于此方法,集合中的对象将始终用作父类的实例,但在其他上下文中,它们的使用方式不同,因此它们被单独保存。例如:
import java.util.ArrayList;
import java.util.Collection;
public class TestClass {
public static int PARENTTYPE=0;
public static int CHILDTYPE=1;
Collection<ParentClass> parentHolder=new ArrayList<ParentClass>();
Collection<ChildClass> childHolder=new ArrayList<ChildClass>();
public TestClass(){
}
public Collection<ParentClass> getHolder(int type){
if (type==PARENTTYPE){
return parentHolder;
}else if (type==CHILDTYPE){
return childHolder; //<--incompatible types
}else{
throw new RuntimeException("Not a valid type");
}
}
public static void main(String args[]){
TestClass test=new TestClass();
Collection<ParentClass> col1=test.getHolder(PARENTTYPE);
Collection<ParentClass> col2=test.getHolder(CHILDTYPE);
}
}
public class ParentClass {
}
public class ChildClass extends ParentClass{
}
但是,我在指定的行收到了不兼容的类型异常。如何编写方法,以便我可以返回声明为包含任何扩展某个类的对象的集合。
答案 0 :(得分:4)
错误原因
引发异常的原因是Collection<ParentClass>
可以包含任何扩展ParentClass
的对象。例如,可以向其添加以下类的实例
public class OtherChildClass extends ParentClass{
}
但是因为“真实”集合是Collection<ChildClass>
,这会引发错误。或者即使您向其添加了ParentClass
,也会引发错误。总的来说还不好。
<强>解决方案强>
但是,可以通过在类型声明中使用Collection<? extends ParentClass>
来解决此问题。这意味着你要返回一个Collection
,它被声明为包含一些可以强制转换为ParentClass
的类,并被称为 contravariance 。这样的集合不能添加新的对象(允许的null异常)因为编译器永远不能保证你试图放入它的内容是有效的。但是它可以保证从它出来的任何东西都可以转换为ParentClass并且可以这样使用。见here for more details。用法示例如下:
import java.util.ArrayList;
import java.util.Collection;
public class TestClass {
public static int PARENTTYPE=0;
public static int CHILDTYPE=1;
ArrayList<ParentClass> parentHolder=new ArrayList<ParentClass>();
ArrayList<ChildClass> childHolder=new ArrayList<ChildClass>();
public TestClass(){
parentHolder.add(new ParentClass());
childHolder.add(new ChildClass());
}
public ArrayList<? extends ParentClass> getHolder(int type){
if (type==PARENTTYPE){
return parentHolder;
}else if (type==CHILDTYPE){
return childHolder; //<-- no longer incompatible types
}else{
throw new RuntimeException("Not a valid type");
}
}
public static void main(String args[]){
TestClass test=new TestClass();
ArrayList<? extends ParentClass> col1=test.getHolder(PARENTTYPE);
ArrayList<? extends ParentClass> col2=test.getHolder(CHILDTYPE);
ParentClass childCastToParent=col2.get(0);
}
}
N.B。 arraylists已被用于简洁,但同样适用于所有集合