接口字段的“公共”和“公共最终”是否冗余?

2022-09-01 01:46:11


我正在阅读这篇文章 为什么在Java中使用静态嵌套接口?特别是第一个答案。在该答案中,在接口字段上使用“公共”或“公共最终”一词是多余的。我的问题是:为什么?为什么要删除它们?如果我有这样的东西:

public interface Int1 {
   public void add();
   void remove(); 
}

这是否意味着我希望方法由任何类实现,而方法仅由同一包的类实现?addremove


答案 1

接口方法的“公共”和“公共最终”是多余的吗?

是的。

接口中的所有方法都是隐式的 和(但不是 )。publicabstractfinal

接口中的所有字段都是隐式的 、和 。publicstaticfinal

JLS指出了这一点。它还指出,可以省略这些修饰符。


为什么?嗯,有各种各样的原因:

  • 字段和方法是隐式的,因为接口的要点是声明一个...其他类可以看到的接口。(如果您想/需要限制访问,这是通过界面本身上的访问修饰符完成的。public

  • 字段是因为如果不是,您将在对象上声明可见的实例字段...这对封装不利。static

  • 字段是因为非最终字段将是声明字段的另一种方式...从OO的角度来看,这是可怕的。finalpublicstatic

  • 方法是因为允许方法体可以有效地将接口转换为抽象类。abstract

在接口中使方法抽象和字段静态的另一个原因是,如果它们不这样做,菱形继承和从两个不同的接口继承方法都会有问题。

但无论哪种方式,这就是Java的定义方式,所以这些问题是没有意义的......除非你正在考虑发明自己的编程语言。

请注意,在 Java 8 中,可以使用修饰符在接口中声明方法。在 Java 9 中,在某些情况下,您可以声明方法。但是使用关键字仍然是多余的。defaultprivatepublic


为什么要删除它们?

您不必删除它们。Java编译器不在乎。您可以删除它们,但不必删除它们,除非您试图遵守某些坚持这一点的Java样式指南。如果你是一致的,你的代码可能会更具可读性,但你可以通过在任何地方使用冗余修饰符来使其一致;例如,添加它们而不是删除它们。

这是否意味着我希望添加方法由任何类实现,而删除仅由同一包的类实现的方法?

不,这并不意味着。或者至少,这对你来说可能意味着,但这并不意味着Java编译器,其他Java工具......或其他人阅读和维护您的代码。海事组织,将任何含义放在是否存在冗余关键字上都是不明智的。


答案 2

不能在接口中声明方法。字段总是,但方法总是(并且从不 )。不能定义仅由同一包中的类实现的接口方法。*来自 Java 语言规范的第 9.3 节finalfinalabstractfinal

接口主体中的每个字段声明都是隐式公共的、静态的和最终的。允许为此类字段冗余指定任何或所有这些修饰符。

以及第9.4节

接口主体中的每个方法声明都是隐式公共的 (§6.6)。

接口主体中的每个方法声明都是隐式抽象的,因此其主体始终由分号表示,而不是块。

允许(但作为样式问题)为接口中声明的方法冗余地指定公共和/或抽象修饰符,但不鼓励这样做。

*正如 Paul Bellora 在评论中指出的那样,如果你想限制接口的可见性,你可以将界面本身设置为包私有(或受保护,甚至私有)。