Why doesn't Java allow private members in interface?

Java

Java Problem Overview


Why doesn't Java allow private members in interface? Is there any particular reason?

Java Solutions


Solution 1 - Java

From the Java Language Spec, (Access Control):

> "The Java programming language provides mechanisms for access control, > to prevent the users of a package or class from depending on > unnecessary details of the implementation of that package or class."

Access control is all about hiding implementation details. An interface has no implementation to hide.

Solution 2 - Java

In Java 9, private methods in interfaces are possible.

Java 9 specifications

> The javac compiler team is pleased announce the availability of compiler support for private methods in interfaces beginning with 9 b54 build of JDK.

Solution 3 - Java

Private interface methods are part of Java 9 as part of JEP-213. Since interfaces in Java 8 can have default methods, private methods allow for multiple default methods to use a shared private method.

Solution 4 - Java

As of Java 8, interfaces can have default methods, and as of Java 9, an interface is allowed to have a private methods which can only be accessed by default methods in the same interface.

Solution 5 - Java

An interface is used for describing an API which is provided by any class implementing the interface. Since an interface from its definition has no state there is no use of declaring field members in it.

Solution 6 - Java

There would be no way to implement such an interface. An answer to a question I posed strongly suggests that it would be impossible (without radically changing the rules) to implement an interface with private methods - this leaves open the question of why protected and package private methods are not allowed.

class OuterClass
{
     void run ( MyInterface x )
     {
           x . publicMethod ( ) ;  // why not?
           x . protectedMethod ( ) ; // why not?
           x . packagePrivateMethod ( ) ; // why not?
           x . privateMethod ( ) ; // why not?
     }

     interface MyInterface
     {
           public abstract void publicMethod ( ) ; // OK

           protected abstract void protectedMethod ( ) ; // why not?

           abstract void packagePrivateMethod ( ) ; // in interface default is public, but why not package private

           private void privateMethod ( ) ; // impossible to implement
     }

     class MyImpl implements MyInterface
     {
           public void publicMethod ( ) { } // ok

           protected void protectedMethod ( ) { } // no sweat

           void packagePrivateMethod ( ) { } // no sweat

           private void privateMethod ( ) { } // not happening
     }
}

The below code should achieve the desired result. Even though all methods are public, only public method is effectively public. protected method is effectively protected. packagePrivateMethod is effectively packagePrivate. privateMethod is effectively private.

class WorkAround
{
     void run ( MyPrivateInterface x )
     {
           x . publicMethod ( ) ;  
           x . protectedMethod ( ) ; 
           x . packagePrivateMethod ( ) ; 
           x . privateMethod ( ) ; 
     }

     public interface MyPublicInterface { void publicMethod ( ) ; }

     protected interface MyProtectedInterface extends MyPublicInterface { void protectedMethod ( ) ; }

     interface MyPackagePrivateInterface extends MyProtectedInterface { void packagePrivateMethod ( ) ; }

     private interface MyPrivateInterface extends MyPackagePrivateInterface { void privateMethod ( ) ; }
}

Solution 7 - Java

According to the Java programming language scope of the private members is limited to the class in which it is declared and can be accessed only by methods of that class. But inteface doesn't have a method body hence there is no use of declaring private members inside an interface.

Solution 8 - Java

Java allows private methods in an interface in Java 9. The default methods were introduced in Java 8. It is possible that multiple default methods want to share some code, then this code can be moved to a private method without exposing it to outer world. This bug has been fixed and starting in JDK 9 build 54, compiler support for private interface methods have been resurrected.

public interface IData{
   default void processData(int data) {
      validate(data);
      // do some work with it
   }
   default void consumeData(int data) {
      validate(data);
      // do some work with it
   }
   private void validate(int data) {
     // validate data
   }
}

Solution 9 - Java

It is because they would be useless.

There would be no way to call a private method.

Private members are an implementation detail. An interface is about the public role that a class can take on.

Solution 10 - Java

private fields would not be completely useless as other fields and inner classes could access them.

However private methods could not be implemented, even in nested classes, making them almost useless. You could read them using reflection, but that is rather an edge case.

Solution 11 - Java

Private members don't make sense in interface. Interface is a way to access a class with defined methods where you don't need to see the inners of that class.

Private members disagree to that.

Solution 12 - Java

> Members of a class that are declared private are not inherited by > subclasses of that class. Only members of a class that are declared > protected or public are inherited by subclasses declared in a package > other than the one in which the class is declared.

Source

So you don't have any working methods in an interface which can work with that private non-inheritable field, Then why should it exist?

Solution 13 - Java

Yep, can't do that. For all those commenting on why it shouldn't:

Imagine I have Class A, which utilizes interface I. Class B, extends Class A, therefore also inheriting all interface methods in A.

Now, imagine I want a private method in Class A, but want it contractually defined for other classes as well (Maybe a class C, which doesn't necessarily extend Class B or A).

Perhaps for an "initialization" method, that I want for all classes using an I interface. But obviously I don't want an initialization method to be public.... since it should only be used once, or as the class deems necessary, not just because you want to use it all willy-nilly.

The only solution is a workaround, or by simply forcing the init method into the classes themselves without an interface.

I understand the reason not too, for sure, but still, it can come in handy sometimes. Clearly Oracle agrees as they're allowing private interface methods in JDK 9.

What I did, for mine anyway, was place a simple boolean variable, that way the interface method (which should be private) can be flagged as true (initialized = true) after being set once. Then when called again the method simply does nothing. This way the interface method can be implemented as public, but since the constructor (of my class) calls the method first, this sets the variable to true, and so it can't be called again.

Otherwise you'd have to try a different workaround if you only want the inner workings of the class to use it.... perhaps a method itself sets a flag on and off as it uses it. When the flag is false, the method does nothing (this would be when someone calls it from outside the class). However, when the classes own methods call it, they quickly set the flag to true, then call the method, then set the flag to false??

In the end kind of mute. Probably just better for now to simply place the private class into the class itself and cut-out the interface altogether.

Solution 14 - Java

Interfaces can't have private members, which includes data variables \ fields as well as methods.

Here is a timeline of how Java interfaces have evolved (source):

  • Java 1.1
    • Nested classes
    • Nested interfaces
  • Java 5
    • Generics
    • Nested enums
    • Nested annotations
  • Java 8
    • Default methods
    • Static methods
  • Java 9
    • Private methods

With the current implementation If the interface members are private, you cannot provide implementation to the methods or cannot access the fields in the implementing class. Therefore, the members of an interface cannot be private. If you try to declare the members of an interface private, a compile-time error is generated saying “modifier private not allowed here”.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondppView Question on Stackoverflow
Solution 1 - JavaMattenView Answer on Stackoverflow
Solution 2 - JavachiperortizView Answer on Stackoverflow
Solution 3 - JavamkobitView Answer on Stackoverflow
Solution 4 - JavaPeter LawreyView Answer on Stackoverflow
Solution 5 - JavagiorashcView Answer on Stackoverflow
Solution 6 - JavaemoryView Answer on Stackoverflow
Solution 7 - JavaNishantView Answer on Stackoverflow
Solution 8 - Javaakhil_mittalView Answer on Stackoverflow
Solution 9 - JavaWW.View Answer on Stackoverflow
Solution 10 - JavaPeter LawreyView Answer on Stackoverflow
Solution 11 - Javajuergen dView Answer on Stackoverflow
Solution 12 - JavaAlireza MohamadiView Answer on Stackoverflow
Solution 13 - JavaTyrael ArchangelView Answer on Stackoverflow
Solution 14 - JavaboardtcView Answer on Stackoverflow