ChatGPT解决这个技术问题 Extra ChatGPT

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

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

Technically it doesn't matter, of course. A class method that implements an interface is always public. But what is a better convention?

Java itself is not consistent in this. See for instance Collection vs. Comparable, or Future vs. ScriptEngine.

It's bad because writing it as public implies that it can be non-public
You should avoid redundant syntax of any form.
@Pacerier, while I agree that it's bad to use public in this context, default interface methods can now (with java 9) be private. I suggest you remove your comment as it is obsolete.
Yes, things are subject to change in Java 9. "Writing it as public implies that it can be non-public". Since exactly that seems to be possible in Java 9, this argument is now in the benefit of indeed writing out public.

P
Pang

The JLS makes this clear:

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.


The JLS link above was for Java 7 at the time I read it. After the comments about Java 9 allowing non-public methods, I just wanted to confirm that very similar wording is still there for SE9 JLS. (public part is same, and/or abstract part has been dropped)
Still true in SE11 JLS
R
Rasmus Faber

The public modifier should be omitted in Java interfaces (in my opinion).

Since it does not add any extra information, it just draws attention away from the important stuff.

Most style-guides will recommend that you leave it out, but of course, the most important thing is to be consistent across your codebase, and especially for each interface. The following example could easily confuse someone, who is not 100% fluent in Java:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}

Do you have a link to such a style-guide?
Consistency is by far the most important thing, and is the answer to 99% of these types of questions.
Agreed re: consistency. Something for your coding standards documents guys :)
Bno: One example is the Java Language Specification, another is Checkstyle.
L
Leo The Four

Despite the fact that this question has been asked long time ago but I feel a comprehensive description would clarify why there is no need to use public abstract before methods and public static final before constants of an interface.

First of all Interfaces are used to specify common methods for a set of unrelated classes for which every class will have a unique implementation. Therefore it is not possible to specify the access modifier as private since it cannot be accessed by other classes to be overridden.

Second, Although one can initiate objects of an interface type but an interface is realized by the classes which implement it and not inherited. And since an interface might be implemented (realized) by different unrelated classes which are not in the same package therefore protected access modifier is not valid as well. So for the access modifier we are only left with public choice.

Third, an interface does not have any data implementation including the instance variables and methods. If there is logical reason to insert implemented methods or instance variables in an interface then it must be a superclass in an inheritance hierarchy and not an interface. Considering this fact, since no method can be implemented in an interface therefore all the methods in interface must be abstract.

Fourth, Interface can only include constant as its data members which means they must be final and of course final constants are declared as static to keep only one instance of them. Therefore static final also is a must for interface constants.

So in conclusion although using public abstract before methods and public static final before constants of an interface is valid but since there is no other options it is considered redundant and not used.


W
Werner Thumann

With the introduction of private, static, default modifiers for interface methods in Java 8/9, things get more complicated and I tend to think that full declarations are more readable (needs Java 9 to compile):

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() {}

}

How can I add default method and specify default access modifier in one line? default default void myDefaultMethod() throws error.
@ajinzrathod default void myDefaultMethod() achieves what you want. Just like with classes, interfaces do not use any keyword to specify package-private, aka "default" visibility - it is simply the standard access modifier when others (public, private, protected) are omitted. I think it might've been more sensible for Oracle to use a different keyword than default (standard perhaps?) for non-abstract non-static interface methods to avoid potential confusion between it and the term "default" being used to mean package-private access modifier
s
swpalmer

I disagree with the popular answer, that having public implies that there are other options and so it shouldn't be there. The fact is that now with Java 9 and beyond there ARE other options.

I think instead Java should enforce/require 'public' to be specified. Why? Because the absence of a modifier means 'package' access everywhere else, and having this as a special case is what leads to the confusion. If you simply made it a compile error with a clear message (e.g. "Package access is not allowed in an interface.") we would get rid of the apparent ambiguity that having the option to leave out 'public' introduces.

Note the current wording at: 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."

See that 'private' IS allowed now. I think that last sentence should have been removed from the JLS. It is unfortunate that the "implicitly public" behaviour was ever allowed as it will now likely remain for backward compatibilty and lead to the confusion that the absence of the access modifier means 'public' in interfaces and 'package' elsewhere.


J
JeeBee

I always write what I would use if there was no interface and I was writing a direct implementation, i.e., I would use public.


Would you also explicitly declare all interface methods abstract?
It's an interface, not an abstract class. As regards to 'public', it's 7 characters that you've typed by the time you think about it, big deal! And it's how it will be defined in the implementation as well, which is +1 for consistency balancing out the -1 for redundancy.
P
PhiLho

I would avoid to put modifiers that are applied by default. As pointed out, it can lead to inconsistency and confusion.

The worst I saw is an interface with methods declared abstract...


Leaving out the public modifier leads to confusion as that means something different everywhere else. The JLS got the advice wrong in this case IMO. It should be a compile error to imply "package private" in an interface. Too late now of course, but hte recommendation to omit 'public' can still change.
c
cretzel

I used declare methods with the public modifier, because it makes the code more readable, especially with syntax highlighting. In our latest project though, we used Checkstyle which shows a warning with the default configuration for public modifiers on interface methods, so I switched to ommitting them.

So I'm not really sure what's best, but one thing I really don't like is using public abstract on interface methods. Eclipse does this sometimes when refactoring with "Extract Interface".


But only if you check the two checkboxes declare methods as public, abstract.
I
Iuliana Cosmina

The reason for methods in interfaces being by default public and abstract seems quite logical and obvious to me.

A method in an interface it is by default abstract to force the implementing class to provide an implementation and is public by default so the implementing class has access to do so.

Adding those modifiers in your code is redundant and useless and can only lead to the conclusion that you lack knowledge and/or understanding of Java fundamentals.


But you can also implement abstract methods that have protected access - in an abstract class. So public isn't a requirement. Adding something explicit that is the same as what would be the default is always redundant, but it is not always useless.
But the question is about interfaces. I did not want to digress. I mean, since Java 8, we can also talk about private and default method in interfaces, right? So this discussion can be made quite long if we want to. ;)
k
k1eran

I prefer skipping it, I read somewhere that interfaces are by default, public and abstract.

To my surprise the book - Head First Design Patterns, is using public with interface declaration and interface methods... that made me rethink once again and I landed up on this post.

Anyways, I think redundant information should be ignored.


Just to clarify, if you omit the public access modifier on the interface declaration then it will not be public and abstract by default. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
R
RustyTheBoyRobot

It's totally subjective. I omit the redundant public modifier as it seems like clutter. As mentioned by others - consistency is the key to this decision.

It's interesting to note that the C# language designers decided to enforce this. Declaring an interface method as public in C# is actually a compile error. Consistency is probably not important across languages though, so I guess this is not really directly relevant to Java.


You write "consistency is the key.." but leaving out the public specifier on an interface method declaration does not mean "package private" as it does everywhere else. It is inconsistent!
T
Tim Boudreau

People will learn your interface from code completion in their IDE or in Javadoc, not from reading the source. So there's no point in putting "public" in the source - nobody's reading the source.


I really have to disagree with the statement that nobody is reading the source. I think a lot of people use for instance F3 in Eclipse to zoom into the code. Tools like Maven offer the option to download the sources, not just the JavaDoc, for a reason.
That's not the exact reason for not adding a public access modifier to a interface. It is by design and after a careful thinking behind it.