我的应用程序有一个简单的插件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;
    }
}


我的要求是:


在内部,ObservableList个中的Layer个可用
API仅公开ListILayer


不幸的是,将ObservableList<Layer>强制转换为List<ILayer>是非法的。

在API中返回List<Layer>会暴露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;
    }
}


主要缺点是调用List<? extends ILayer> layers = plotter.getLayers();的人将无法添加到列表中:layers.add(someLayer);无法编译。这可能是也可能不是问题。

关于java - 干净的解决方案,将“ObservableList <Foo>”转换到“List <IFoo>”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34045925/

10-11 01:31