是否应使用或不使用公共访问修饰符声明Java接口中的方法?

Should methods in a Java interface be declared with or without a public access modifier?

Java接口中的方法是否声明有或不使用EDCOX1?0访问修改器?

从技术上讲,这当然不重要。实现interface的类方法始终是public。但什么是更好的约定呢?

Java本身并不是一致的。例如,参见CollectionComparableFutureScriptEngine


JLS明确表示:

It is permitted, but discouraged as a matter of style, to redundantly specify the public and/or abstract modifier for a method declared in an interface.


应该在Java接口中省略公共修饰符(在我看来)。

因为它没有添加任何额外的信息,它只是把注意力从重要的东西上移开。

大多数样式指南都建议您不要使用它,但当然,最重要的是跨代码库保持一致,尤其是对于每个接口。下面的例子很容易迷惑某人,他不是100%流利的Java:

1
2
3
4
public interface Foo{
  public void MakeFoo();
  void PerformBar();
}


尽管这个问题早就被问到了,但我觉得一个全面的描述可以解释为什么在方法之前不需要使用公共抽象,在接口常量之前不需要使用公共静态final。

首先,所有接口用于为一组不相关的类指定通用方法,每个类都将有一个唯一的实现。因此,不能将访问修饰符指定为private,因为它不能被要重写的其他类访问。

第二,尽管可以启动接口类型的对象,但是接口是由实现它而不是继承它的类实现的。而且,由于接口可能由不同的不在同一个包中的不相关类实现(实现),因此受保护的访问修饰符也无效。所以对于访问修饰符,我们只剩下公共选择。

第三,接口没有任何数据实现,包括实例变量和方法。如果有逻辑原因要在接口中插入实现的方法或实例变量,那么它必须是继承层次结构中的超类,而不是接口。考虑到这一事实,由于接口中不能实现任何方法,因此接口中的所有方法都必须是抽象的。

第四,接口只能包含常量作为其数据成员,这意味着它们必须是最终的,当然,最终常量声明为静态的,以只保留它们的一个实例。因此,静态final也是接口常量的必备项。

因此,综上所述,尽管使用public abstract before方法和public static final before接口的常量是有效的,但是由于没有其他选项,因此它被认为是多余的,不被使用。


随着EDCOX1、0、EDCOX1、1、EDCOX1、2对Java 8/9接口方法的修改,事情变得更加复杂,我倾向于认为完全声明更可读(需要Java 9编译):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}

我使用带有public修饰符的declare方法,因为它使代码更具可读性,特别是语法突出显示。不过,在我们最新的项目中,我们使用了checkStyle,它在接口方法上显示带有public修饰符的默认配置的警告,所以我切换到committing它们。

所以我不确定什么才是最好的,但我真正不喜欢的一件事是在接口方法上使用public abstract。Eclipse在使用"提取接口"重构时有时会这样做。


我将避免放置默认应用的修饰符。正如所指出的,这可能导致不一致和混淆。

我看到的最糟糕的是一个与声明为abstract的方法的接口…


如果没有接口,并且我正在编写一个直接的实现,也就是说,我将使用public,那么我总是编写将要使用的内容。


我更喜欢跳过它,我在某个地方读到接口默认为publicabstract

令我惊讶的是,书的头一个设计模式,是使用public与接口声明和接口方法…这让我再次思考,我在这篇文章上找到了答案。

无论如何,我认为多余的信息应该被忽略。


我不同意流行的答案,即公开意味着还有其他选择,所以它不应该存在。事实上,现在Java 9和其他的还有其他的选择。

我认为Java应该强制/要求"公共"被指定。为什么?因为没有修饰符意味着"包"可以访问其他任何地方,而将其作为特殊情况会导致混乱。如果您只是简单地将其设置为一个编译错误,并带有一条明确的消息(例如,"在接口中不允许包访问"),那么我们就可以消除明显的模糊性,即可以选择不使用"public"引入。

注意:https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html jls-9.4

"A method in the body of an interface may be declared public or
private (§6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of
style, to redundantly specify the public modifier for a method
declaration in an interface."

请注意,现在允许使用"private"。我认为最后一句应该从JLS中删除。不幸的是,"隐式公共"行为曾经被允许,因为它现在可能会保持向后兼容,并导致混淆,即缺少访问修饰符意味着接口中的"公共"和其他地方的"包"。


接口中的方法默认为公共的和抽象的原因在我看来是非常合理和明显的。

接口中的一种方法。默认情况下,它是抽象的,强制实现类提供实现,默认情况下是公共的,因此实现类有权这样做。

在代码中添加这些修饰符是多余的和无用的,只能导致你缺乏对Java基础知识和/或理解的结论。


这完全是主观的。我省略了多余的public修饰语,因为它看起来很杂乱。正如其他人所提到的,一致性是这个决定的关键。

有趣的是,C语言设计师决定实施这一点。在C中将接口方法声明为public实际上是一个编译错误。一致性在跨语言中可能并不重要,所以我想这不是真正与Java直接相关的。


人们将从IDE或JavaDoc中的代码完成学习您的界面,而不是从读取源代码开始。所以没有必要把"公开"放在源代码中——没有人在读源代码。