当前位置: 首页 > 知识库问答 >
问题:

Java8默认方法为特征:安全吗?

陶鸿畴
2023-03-14

在Java8中使用缺省方法作为穷人版本的traits是一种安全的做法吗?

有人说,如果你只是为了熊猫而使用它们,可能会让熊猫伤心,因为它很酷,但这不是我的本意。人们还经常提醒说,引入缺省方法是为了支持API演进和向后兼容性,这是真的,但这并不使使用它们作为特征本身是错误的或扭曲的。

我脑海中有以下实际用例:

public interface Loggable {
    default Logger logger() {
        return LoggerFactory.getLogger(this.getClass());
    }
}

或者,定义periodtrait:

public interface PeriodeTrait {
    Date getStartDate();
    Date getEndDate();
    default isValid(Date atDate) {
        ...
    }
}

关于SO的几个问题与Java vs Scala特性有关;这不是重点。我也不仅仅是在征求意见。相反,我在寻找一个权威的答案,或者至少是实地的洞察力:如果你在你的公司项目中使用了默认方法作为特征,那么它是不是变成了一个定时炸弹?

共有1个答案

孙梓
2023-03-14

简短的回答是:如果你安全地使用它们,它是安全的:)

尖刻的回答:告诉我你所说的特质是什么意思,也许我会给你一个更好的答案:)

严肃地说,“特质”一词并没有很好的定义。许多Java开发人员最熟悉用Scala表示的特性,但Scala远远不是第一种具有特性的语言,不管是名义上还是实际上。

以下是一些完全符合设计目标的用例:

>

  • 界面演变。在这里,我们将一个新方法添加到一个现有的接口中,该接口具有一个合理的默认实现,即该接口上的现有方法。一个示例是将foreach方法添加collection中,其中默认实现是根据iterator()方法编写的。

    “可选”方法。在这里,接口的设计者说“如果实现者愿意承受功能上的限制,他们就不需要实现这个方法”。例如,iterator.remove被赋予一个默认值,该默认值抛出unsupportedoperationexception;由于iterator的绝大多数实现无论如何都具有此行为,因此默认值使此方法本质上是可选的。(如果AbstractCollection中的行为被表示为Collection上的默认值,我们可能会对变异方法执行相同的操作。)

    组合子。这些是组合方法,它们基于当前实例实例化接口的新实例。例如,方法predicate.and()comparator.thencomparate()是组合符的示例。

    如果您提供了一个缺省实现,那么您还应该为缺省提供一些规范(在JDK中,我们为此使用@implspecjavadoc标记),以帮助实现人员理解他们是否要重写方法。一些默认值,如方便方法和组合子,几乎从不被覆盖;其他方法,如可选方法,经常被重写。您需要提供足够的规范(而不仅仅是文档)来说明缺省promise要做什么,这样实现者就可以做出是否需要重写缺省的明智决定。

  •  类似资料:
    • 主要内容:1 Java8 默认方法的介绍,2 Java8 默认方法的案例1 Java8 默认方法的介绍 Java提供了一种在接口内部创建默认方法的功能。在接口内部定义并带有默认标记的方法称为默认方法。这些方法是非抽象方法。 2 Java8 默认方法的案例 在下面的示例中,Sayable是一个功能接口,其中包含默认值和抽象方法。默认方法的概念用于定义具有默认实现的方法。您还可以覆盖默认方法,以为该方法提供更具体的实现。 输出结果为:  

    • 本文向大家介绍Java8新特性之默认方法(default)浅析,包括了Java8新特性之默认方法(default)浅析的使用技巧和注意事项,需要的朋友参考一下 一、什么是默认方法,为什么要有默认方法 简单说,就是接口可以有实现方法,而且不需要实现类去实现其方法。只需在方法名前面加个default关键字即可。 为什么要有这个特性?首先,之前的接口是个双刃剑,好处是面向抽象而不是面向具体编程,缺陷是,

    • 问题内容: 拥有具有默认方法的接口的动态代理,如何调用默认方法?通过使用类似的方法,您可以得到名为的代理调用处理程序(这在某种程度上是正确的,因为您没有为此接口实现的类)。 我有一个使用ASM来创建实现接口的类并将此类调用委派给此类实例的解决方法。但这不是一个好的解决方案,特别是如果默认方法调用其他接口方法(您将获得委托人乒乓球)。JLS对此问题出人意料地保持沉默… 这里是一个小代码示例: 问题答

    • 问题内容: 默认方法是Java工具箱中一个不错的新工具。但是,我试图编写一个定义方法版本的接口。Java告诉我,这是禁止的,因为in中声明的方法可能无法编辑。为什么会这样呢? 我知道有一个“基类始终获胜”规则,因此默认情况下(pun;),方法的任何实现都会被该方法覆盖。但是,我认为没有理由为什么规范中的方法不应有例外。特别是因为它具有默认实现可能非常有用。 那么,Java设计者决定不允许方法覆盖方

    • 我们举个例子: 一个常见的解决方案是转移到一个抽象类,但是在我的具体案例中,我有一个枚举的接口,所以在这里不适用。我想这不是被忽略了,就是因为接口背后的原始想法,即它们是可用方法的“契约”,但我想我需要关于这是怎么回事的输入。 我读过“为什么Java 8接口方法中不允许使用”final“?”,其中说: 默认方法的基本思想是:它是具有默认实现的接口方法,派生类可以提供更具体的实现 与关联问题一样,由

    • 默认方法是Java工具箱中一个很好的新工具。然而,我试图编写一个接口,定义方法的版本。Java告诉我这是禁止的,因为方法是在可能不是默认值。为什么会是这种情况? 我知道有“基类总是赢”的规则,所以默认情况下(双关语;),方法的任何实现都将被中的方法覆盖。但是,我看不出规范中的中的方法不应该有例外的原因。特别是对于来说,拥有一个默认实现可能非常有用。 那么,Java设计人员决定不允许方法重写中的方法