42

"Support for private methods in interfaces was briefly in consideration for inclusion in Java SE 8 as part of the effort to add support for Lambda Expressions, but was withdrawn to enable better focus on higher priority tasks for Java SE 8. It is now proposed that support for private interface methods be undertaken thereby enabling non abstract methods of an interface to share code between them."

So says the specification for http://openjdk.java.net/jeps/213 and says in bug report https://bugs.openjdk.java.net/browse/JDK-8071453 .

But I can't really think of any use-case where this is necessary, even with the short explanation given above. May I ask for an example where "private interface methods" are useful in terms of code?

EDIT: So the answer is that due to how default implementations have been added to interfaces in Java 8, there can be instances where the default implementations are using the same codebase.

For example,

public interface MyInterface {
     default void initializeMyClass(MyClass myClass, Params params) {
         //do magical things in 100 lines of code to initialize myClass for example
     }

     default MyClass createMyClass(Params params) {
         MyClass myClass = new MyClass();
         initializeMyClass(myClass, params);
         return myClass;
     }

     default MyClass createMyClass() {
         MyClass myClass = new MyClass();
         initializeMyClass(myClass, null);
         return myClass;
     }
}

Silly example, I know. But let's say that we want to use initializeMyClass(MyClass, Params) in both methods. However, if we do it like this (default method), then initializeMyClass(MyClass, Params) will be part of the public interface! To prevent that from happening, we can only keep the code of entire initializeMyClass(MyClass, Params) inside the createMyClass() default methods. Which results in code duplication, which is undesirable.

Therefore, this causes problem with refactoring, and to remove such code duplication, private default methods are allowed.

Thanks for answering!

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428

3 Answers3

39

Interfaces can now have default methods. These were added so that new methods could be added to interfaces without breaking all classes that implement those changed interfaces.

If two default methods needed to share code, a private interface method would allow them to do so, but without exposing that private method and all its "implementation details" via the interface.

mk.
  • 11,360
  • 6
  • 40
  • 54
  • 2
    Are such methods basically syntactic sugar to call static methods which could otherwise be package-private? – supercat Mar 13 '15 at 20:11
  • 1
    No, because you can override them as instance methods in your implementation, which is something you can't do if you use a static method. – mk. Mar 13 '15 at 20:13
  • 4
    How would such overriding work? What could the override access, and what could access the override? – supercat Mar 13 '15 at 20:26
  • It behaves exactly the same as defining any other interface method (but because there's some code already there, we call it redefining/overriding). If you redefine a default method, you can pretend that you implemented an abstract interface method. – mk. Mar 13 '15 at 20:35
  • By my understanding, Java requires that methods which implement interfaces be private. Would code which wanted to override an interface's private method be able to do so without making the override public? Would an implementation of an interface have access to any of the interface's private members [even though an implementing class could in theory copy/paste private interface members for its own use, that could break things if the members later change in the interface but not in the class's own copy). – supercat Mar 13 '15 at 20:56
  • 3
    I now realize that you might be talking about private interface methods, while I'd assumed we were talking about default methods :) I don't know how private methods will be implemented, but I don't think they'd use static methods, since you'd often want to use other instance methods to compute a result. Maybe this is worth making its own question... – mk. Mar 13 '15 at 21:14
  • Oh, I see. Considering it is `private`, I guess it cannot be overridden in any way as only the interface is the one to see it, but it can be used for implementation in default methods, without "polluting" the interface with internal logic. Makes sense, thank you! – EpicPandaForce Mar 14 '15 at 08:39
  • 3
    So, why don't use an abstract class, then? Wanna say: they aren't too many things for an interface? I see an interface as a contract, not as an implementation and I accept default methods for the sake of lambdas, but I think that this is getting out of hands... They should allow multiple inheritance and stop it. – inigoD Apr 25 '17 at 07:28
  • [Here](https://stackoverflow.com/a/46219127/1746118) is an example for a use-case I tried framing for SO question sorting. – Naman Sep 14 '17 at 13:27
6

Why not simply (simply = using Java8):

PS: because of private helper is not possible in Java

public interface MyInterface {
 private static class Helper{
     static initializeMyClass(MyClass myClass, Params params){
         //do magical things in 100 lines of code to initialize myClass for example
     }
 }

 default MyClass createMyClass(Params params) {
     MyClass myClass = new MyClass();
     Helper.initializeMyClass(myClass, params);
     return myClass;
 }

 default MyClass createMyClass() {
     MyClass myClass = new MyClass();
     Helper.initializeMyClass(myClass, null);
     return myClass;
 }
}
Pang
  • 9,564
  • 146
  • 81
  • 122
maxim_ge
  • 1,153
  • 1
  • 10
  • 18
  • Nice trick, probably because it's slightly less convenient but it's a nice trick! – EpicPandaForce Jun 02 '17 at 16:54
  • I use such helpers widely for the "ages". A bit strange that programming language is extended in this way for such purpose, additional level of unnecessary complication, from my POV. – maxim_ge Jun 05 '17 at 09:06
  • private static class doesn't compile with my eclipse here – Werner Thumann Jul 02 '17 at 07:52
  • @maxim_ge I don't know how your compiler allow you to use such a declaration!!! but it does not compile with my Java 8u131 unless I use public or package level for the `Helper` class! – O.Badr Aug 07 '17 at 09:31
  • 1
    @maxim_ge This will compile only if you remove the private and static keywords form the class declaration. Even then this is not the same as the private methods in interfaces. You still can reach the `Helper` class by typing `MyInterface.Helper`. Private methods in interfaces are fully hidden and unreachable from outside of the interface. – gajos Aug 31 '17 at 14:45
  • @WernerThuman and others - you are right, correction is added. – maxim_ge Sep 05 '17 at 10:05
3

Java 9 allows declaring a private method inside the interface. Here is the example of it.

interface myinterface {
    default void m1(String msg){
        msg+=" from m1";
        printMessage(msg);
    }
    default void m2(String msg){
        msg+=" from m2";
        printMessage(msg);
    }
    private void printMessage(String msg){
        System.out.println(msg);
    }
}
public class privatemethods implements myinterface {
    public void printInterface(){
        m1("Hello world");
        m2("new world");
    }
    public static void main(String[] args){
        privatemethods s = new privatemethods();
        s.printInterface();
    }
}

For that, you need to update jdk up to 1.9 version.

Dhiral Kaniya
  • 1,941
  • 1
  • 19
  • 32