Interface 在接口中使用默认方法是避免代码重复的好模式吗?

Interface 在接口中使用默认方法是避免代码重复的好模式吗?,interface,java-8,code-duplication,default-method,Interface,Java 8,Code Duplication,Default Method,数据持有者类中存在大量代码重复,这些代码可以序列化为XML字符串: public String toXml() throws JAXBException { final JAXBContext context = JAXBContext.newInstance(this.getClass()); final Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshall

数据持有者类中存在大量代码重复,这些代码可以序列化为XML字符串:

public String toXml() throws JAXBException {
    final JAXBContext context = JAXBContext.newInstance(this.getClass());
    final Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    final StringWriter stringWriter = new StringWriter();
    marshaller.marshal(this, stringWriter);
    return stringWriter.toString();
}
为什么不将此代码移动到具有默认实现的单个接口?因此,一个简单的
实现ToXmlUtf8
就足以共享默认实现并避免代码重复:

public interface ToXml {
    default String toXml() throws JAXBException {
        final JAXBContext context = JAXBContext.newInstance(this.getClass());
        final Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        final StringWriter stringWriter = new StringWriter();
        marshaller.marshal(this, stringWriter);
        return stringWriter.toString();
    }
}
以前有人成功地这样做过吗

其他解决方案

我还可以想象使用注释生成此代码


有现成的解决方案吗?

如果您使用完全相同的方法,那么接口将不起作用,您要做的是创建一个静态方法并将其放入一个

如果您使用完全相同的方法,那么接口将不起作用,您要做的是创建一个静态方法并将其放入一个

是,默认方法可以这样使用

虽然默认方法的预期用例是在不破坏旧代码的情况下向现有接口添加新功能,但是默认方法还有其他用途。默认方法也用于在Java8中添加的接口,例如在
Java.util.Predicate
中,因此,即使是Java设计人员也认识到,向现有接口添加新功能并不是默认方法的唯一有效用法


一个缺点可能是,实现的接口是类的公共契约的一部分,但在您的情况下,这似乎不是问题。

是的,默认方法可以以这种方式使用

虽然默认方法的预期用例是在不破坏旧代码的情况下向现有接口添加新功能,但是默认方法还有其他用途。默认方法也用于在Java8中添加的接口,例如在
Java.util.Predicate
中,因此,即使是Java设计人员也认识到,向现有接口添加新功能并不是默认方法的唯一有效用法


缺点可能是实现的接口是类的公共契约的一部分,但在您的情况下,这似乎不是问题。

似乎是这样。您是否创建了一个小测试来尝试它?将为该代码使用一个公共父类,而不是默认方法,请参阅-或在其他地方使用类似
String-toXml(Object-Object)
的实用方法。默认接口解决方案编译,是的。抽象父类限制类层次结构。对于具有
Util.toXml(Object)
的调用者来说,Util类不是那么好,而Object as签名是丑陋的。至少使用一个标记接口。反对
默认方法的参数是什么?我无法从链接文章中提取真正的参数。只是为了扩展现有接口引入了默认方法……我不熟悉“默认方法”。这是什么版本的Java?您是否可以添加适当的标记,使其更明显,这在旧版本中不可用?似乎如此。您是否创建了一个小测试来尝试它?将为该代码使用一个公共父类,而不是默认方法,请参阅-或在其他地方使用类似
String-toXml(Object-Object)
的实用方法。默认接口解决方案编译,是的。抽象父类限制类层次结构。对于具有
Util.toXml(Object)
的调用者来说,Util类不是那么好,而Object as签名是丑陋的。至少使用一个标记接口。反对
默认方法的参数是什么?我无法从链接文章中提取真正的参数。只是为了扩展现有接口引入了默认方法……我不熟悉“默认方法”。这是什么版本的Java?您是否可以添加适当的标记,使其更明显地表明这在旧版本中不可用?对于使用
Util.toXml(Object)
和Object as signature的调用者来说,Util类不太好。至少要使用一个标记接口。我建议您阅读相关文章,了解如何使用接口来解决此问题。对于使用
Util.toXml(Object)
的调用方来说,Util类并不是那么好,而Object as signature是丑陋的。至少要使用一个标记接口。我建议您阅读关于如何使用接口来解决这个问题的文章。