Rya*_*ins 2 java collections covariance
我试图编写一些看起来像这样的代码:
public List<IObject> getObject(){
ArrayList<ConcreteObject> objects = new ArrayList<ConcreteObject>();
return objects;
}
Run Code Online (Sandbox Code Playgroud)
(ConcreteObject实现IObject的位置)
这根本不起作用.它给出了编译器错误.Java是否有计划在未来支持这一点?到那时为止,最好的解决方法是什么?我最终做的是:
public List<IObject> getObject(){
List<IObject> objects = new ArrayList<IObject>();
return objects;
}
Run Code Online (Sandbox Code Playgroud)
这可行,也许这样做没有任何不良副作用.这是普遍接受的最佳方法吗?
Kon*_*lph 11
Java已经支持此功能,您只需要使用它.有关入门知识,请阅读Sun 的Wildcards教程.
你想要的是以下内容:
public List<? extends IObject> getObject(){
ArrayList<ConcreteObject> objects = new ArrayList<ConcreteObject>();
return objects;
}
Run Code Online (Sandbox Code Playgroud)
或者,可以使用不安全的演员:
public <T extends IObject> List<T> getObject(){
ArrayList<T> objects = (ArrayList<T>) new ArrayList<ConcreteObject>();
return objects;
}
Run Code Online (Sandbox Code Playgroud)
...但是当您尝试使用无效类型访问其元素时,此方法相当脆弱并将抛出运行时异常(发出编译错误信号除外):
@SuppressWarnings("unchecked")
public <T extends IObject> List<T> getObject(){
ArrayList<T> objects = (ArrayList<T>) new ArrayList<ConcreteObject>();
objects.add(new ConcreteObject());
return objects;
}
…
List<OtherConcreteObject> objects = getObject(); // Works.
OtherConcreteObject obj = OtherConcreteObject.get(0); // Throws CCE.
Run Code Online (Sandbox Code Playgroud)
这将导致ClassCastException
运行时跟随:" ConcreteObject
无法转换为OtherConcreteObject
" - 这是相当糟糕的,因为代码站在上面,它应该成功.
因此,您应该尝试避免使用此方法.
由于Java Generics Tutorial中最佳描述的原因,这是非法的
从那里做一个例子并将其应用于您的案例:
List<ConcreteObject> concreteObjects = new ArrayList<ConcreteObject>();
List<IObject> objects = concreteObjects; // assume it's legal
objects.add(new IObject() { // anonymous or some other (incompatible with ConcreteObject) implementation
});
ConcreteObject co = concreteObjects.get(0); // Profit! er... I mean error
Run Code Online (Sandbox Code Playgroud)