为什么Java 8接口方法不允许使用“final”关键字?

11 浏览
0 Comments

为什么Java 8接口方法不允许使用“final”关键字?

Java 8中最实用的功能之一是接口上的新 default 方法。它们被引入主要有两个原因(也可能有其他原因):

从API设计者的角度来看,我希望能够在接口方法上使用其他修饰符,例如 final。在添加方便方法时,这将是有用的,可以防止在实现类中“意外”覆盖:

interface Sender {
    // Convenience method to send an empty message
    default final void send() {
        send(null);
    }
    // Implementations should only implement this method
    void send(String message);
}

如果 Sender 是一个类,上述技巧已经是常见做法:

abstract class Sender {
    // Convenience method to send an empty message
    final void send() {
        send(null);
    }
    // Implementations should only implement this method
    abstract void send(String message);
}

现在,defaultfinal 显然是相互矛盾的关键字,但默认关键字本身 不是必需的,因此我认为这种矛盾是有意而为之的,以反映“带有方法体的类方法”(仅方法)和“带有方法体的接口方法”(默认方法)之间微妙差别,即我尚未理解的差别。

在某个时刻,对于接口方法的 staticfinal 修饰符的支持还未被完全探索,引用Brian Goetz的说法

另外一个方面是我们会为接口提供类构建工具的支持的深度,比如 final 方法,private 方法,protected 方法,static 方法等。答案是:我们现在还不知道

自 2011 年底以来,显然,在接口中添加了对 static 方法的支持。显然,这为 JDK 库本身增加了很多价值,例如 Comparator.comparing()

问题:

为什么在 Java 8 接口中没能实现 final(以及 static final)?

admin 更改状态以发布 2023年5月20日
0
0 Comments

在lambda邮件列表中,有很多关于这个的讨论。其中似乎包含有关所有这些内容的讨论之一是:关于Varied interface method visibility (was Final defenders)

在这个讨论中,原始问题的作者Talden提出了与您的问题非常类似的问题:original question

将所有接口成员设为公共成员的决定确实是一个不幸的决定。在内部设计中使用接口将会暴露实现的私有细节。

这是一个难以修复的问题,因为要修复它就必须在语言中添加一些模糊或不兼容的细节。这样的兼容性问题和潜在的微妙性质是不可想象的,因此必须存在一个不会破坏现有代码的解决方案。

重新引入“package”关键字作为访问修饰符是可行的吗?在接口中缺少访问修饰符将意味着公共访问,而在类中缺少访问修饰符则意味着包访问。哪些修饰符在接口中有意义尚不清楚--尤其是如果我们要确保访问修饰符在类和接口中具有相同的含义,以减少对开发者的知识负担。

在缺少默认方法的情况下,我会猜测接口成员的访问修饰符必须至少与接口本身的可见性一样(这样接口才能在所有可见的上下文中被实现)--但是有了默认方法,就不那么确定了。

是否已经有明确的沟通,讨论是否可以进行讨论?如果没有,是否应该在其他地方进行讨论。

最终,Brian Goetz给出了答案

是的,这个问题已经在研究了。

但是,让我设定一些现实的期望 - 语言/VM功能有很长的引导时间,即使像这样看似微不足道的功能。提议Java SE 8的新语言功能的时间几乎已经过去了。

因此,最有可能的原因是它从未被实现,因为它从未包含在范围内。它从未被提议成考虑的时间。

在另一个关于主题的激烈讨论关于最终防御者方法中,Brian再次表示

你已经得到了你所期望的。这就是这个特性增加的——行为的多重继承。当然,我们知道人们会将它们用作特性。我们已经努力确保它们所提供的继承模型足够简单和清晰,让人们在广泛的情况下能够取得良好的结果。与此同时,我们选择不将它们推向超出简单和干净的边界,这在某些情况下会引起“哦,你没做到足够”的反应。但真的,这个帖子大部分看起来都在抱怨杯子只有98%满。我会接受那98%并继续前进!

所以这就加强了我的理论,即它根本不是范围或设计的一部分。他们所做的就是提供足够的功能来处理API演变的问题。

0