从指定它返回Collection 的方法返回Collection
我正在尝试编写一个方法来返回一个集合(例如Arraylist),该集合使用generics声明为包含父类或扩展父类的类 。 对于此方法,集合中的对象将始终用作父类的实例,但在其他上下文中,它们的使用方式不同,因此它们被单独保存。 例如:
import java.util.ArrayList; import java.util.Collection; public class TestClass { public static int PARENTTYPE=0; public static int CHILDTYPE=1; Collection parentHolder=new ArrayList(); Collection childHolder=new ArrayList(); public TestClass(){ } public Collection 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 col1=test.getHolder(PARENTTYPE); Collection col2=test.getHolder(CHILDTYPE); } }
public class ParentClass { }
public class ChildClass extends ParentClass{ }
但是,我在指定的行收到不兼容的类型exception。 我如何编写方法,以便我可以返回声明为包含任何扩展某个类的对象的集合。
错误原因
引发exception的原因是Collection
可以包含任何扩展ParentClass
对象 。 例如,可以向其添加以下类的实例
public class OtherChildClass extends ParentClass{ }
但是因为“真正的”集合是Collection
这会引发错误。 或者即使您向其添加了ParentClass
,也会引发错误。 总而言之不好。
解
这可以通过使用Collection extends ParentClass>
来解决Collection extends ParentClass>
在类型声明中Collection extends ParentClass>
。 这意味着您将返回一个声明为包含某些类的Collection
,该类可以转换为ParentClass
并称为逆变 。 这样的集合不能添加新对象 (允许的nullexception),因为编译器永远不能保证您尝试放入它的内容是有效的。 但它可以保证从它出来的任何东西都可以转换为ParentClass并且可以这样使用。 有关详细信息,请参见此处 用法示例如下:
import java.util.ArrayList; import java.util.Collection; public class TestClass { public static int PARENTTYPE=0; public static int CHILDTYPE=1; ArrayList parentHolder=new ArrayList (); ArrayList childHolder=new ArrayList (); 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); } }
NB arraylists用于简洁,但同样适用于所有集合