在不影响现有系统的情况下更新新Java库

时间:2015-10-20 07:34:57

标签: java api class interface classloader

假设我创建了一个库并在整个公司进行分发,并在每个项目中使用它。

Library是1.0,假设我有一个Componentble接口。

public interface Componentble {
    public String getComponentId();
}

我做了一些修改并更新了jar的1.1和Componentble接口修改如下。

public interface Componentble {
    public String getComponentId();
    public Componentble getParentComponent();
}

当这个jar应用于现有项目时,它会产生编译错误。 我想做这个修改并更新jar。但案例是它不应该影响现有项目。

这样做的最佳方法是什么。 创建ComponentbleV2并在新项目中要求使用ComponentbleV2而不是Componentble。

或创建自定义类加载器并执行需要。

我想要的答案是我们如何修改api并应用于现有项目,而不包括现有项目的任何编译问题。

3 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是使用@Deprecated在旧界面中注释方法,并在javadocs中解释要使用的内容。

有关该文档的更多文档,请参阅Oracle documentation on @Deprecated

为了向后兼容,您现在必须保留两个接口。这可能需要在接口的实现中进行一些自定义。有一段时间,在您经历了几个版本之后,您可以删除旧界面。

确保正确记录已弃用的方法,以便使用它的开发人员知道要使用的内容以及在哪里找到它。

答案 1 :(得分:2)

从Java 8开始,您可以为接口方法提供默认实现。它们是为你的问题而发明的。

public interface Componentble {
    public String getComponentId();
    public default Componentble getParentComponent() {
        return null;
    }
}

答案 2 :(得分:2)

两个接口

无需弃用旧版本。 创建两个接口,新接口扩展旧接口。

public interface Componentble {
    public String getComponentId();
}

public interface ComponentbleWithStructure extends Componentble {
    public Componentble getParentComponent();
}

实现接口应该意味着实现者遵循该接口的契约。

通过这种方式,您知道任何实现这两者的类都已重新编译以适应新合同,而仅实现旧合同的类仍遵循旧合同。

使用示例:

void doStuff(Componentble component){
    if(component instanceof ComponentbleWithStructure){
        Componentble parent=((ComponentbleWithStructure)component).getParentComponent();
        ....
    }
    ....
}

默认实施

只有在可以使用旧接口表达新功能时,java8方式才有用。例如,如果你有一个可以查找父母的服务,你可以写。

public interface Componentble {
    public String getComponentId();
    public default Componentble getParentComponent() {
        return ParentLookUpService.getParent(getComponentId());
    }
}

通过这种方式,您将了解使用新界面的所有实例都具有正确的实现。