gro*_*taj 2 java generics casting javafx interface
我的应用程序有一个简单的插件API.它打包在一个单独的JAR中,插件开发人员可以使用它.核心应用程序实现API中包含的接口,并将它们暴露给加载的插件ServiceLoader.
考虑以下代码:
public interface ILayer {}
public class Layer implements ILayer {
public void internalMethod() { /*snip*/ }
}
public interface IPlotter {
List<ILayer> getLayers();
}
public class Plotter implements IPlotter {
private ObservableList<Layer> layers = FXCollections.observableArrayList();
@Override
public ObservableList<Layer> getLayers() { // incompatible returned type
return layers;
}
}
Run Code Online (Sandbox Code Playgroud)
我的要求是:
ObservableList的Layers是可用List的ILayer小号不幸的是,铸造ObservableList<Layer>到List<ILayer>是违法的.
List<Layer>在API中返回会暴露internalMethod()出来Layer,所以这没有用.
我也可以private ObservableList<ILayer> layers,然后实际存储Layer内部,但这需要每次使用时都会投射它的项目internalMethod(),我对这个想法并不是很热心.
这个问题有一个干净的解决方案吗?
一种选择是更改接口方法的签名以允许返回ILayer的子类型:
interface IPlotter {
List<? extends ILayer> getLayers();
}
class Plotter implements IPlotter {
private ObservableList<Layer> layers = FXCollections.observableArrayList();
@Override
public List<? extends ILayer> getLayers() {
return layers;
}
}
Run Code Online (Sandbox Code Playgroud)
主要的缺点是有人调用List<? extends ILayer> layers = plotter.getLayers();将无法添加到列表:layers.add(someLayer);将无法编译.这可能是也可能不是问题.