假设我创建了一个库并在整个公司进行分发,并在每个项目中使用它。
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并应用于现有项目,而不包括现有项目的任何编译问题。
答案 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());
}
}
通过这种方式,您将了解使用新界面的所有实例都具有正确的实现。