Magnus Gaertner
Magnus Gaertner

Reputation: 33

Java: invoke a default method in another default method of the same interface

I'm very new to the java 8 features and try to understand default methods. Is there an easier way to invoke a default method by another default method of the same interface than using an anonymous class? For example:

public class Frame{

    public static void main(String... args){
        Frame.C c= new Frame.C();
        c.doSomething();
    }

    public interface A{
        public default void doSomething(){
            System.out.println("A");
        }
    }

    public interface B extends A {
        @Override
        public default void doSomething(){
            System.out.println("B");

            //is there an easier way to invoke that method??
            new B(){}.other();
        }
        default public void other(){
            //doSomething();
            System.out.println("other");
        }
    }

    public static class C implements B{
        @Override 
        public void other(){
            Lambda.B.super.other();
            System.out.println("C");

        }
    }

}

Upvotes: 3

Views: 151

Answers (1)

Holger
Holger

Reputation: 298153

Your intention is not entirely clear, but the construct new B(){}.other(); implies two things:

  1. You don’t want to invoke an overriding method implementation
  2. The instance on which you invoke other() is obviously irrelevant when invoking it on an entirely different instance (new B(){}) is a viable solution

These two things together imply that you should use a static method instead:

public interface B extends A {
    @Override
    public default void doSomething(){
        System.out.println("B");

        otherInB();
    }
    default public void other(){
        otherInB();
    }
    static void otherInB() {
        //doSomething();
        System.out.println("other");
    }
}

Since your original method names did not carry useful information, it’s not possible to suggest a useful name for that static method either.

Note that Java 9 is going to introduce support for private methods in interfaces which allows hiding otherInB() to other classes and even making it non-static in case it has to use other methods on the same instance.

If the visibility of the method in Java 8 is an issue, consider that the actual place of a non-polymorphic method is irrelevant, so you can always use a companion class:

public interface B extends A {
    @Override
    public default void doSomething(){
        System.out.println("B");

        BHelper.other();
    }
    default public void other(){
        BHelper.other();
    }
}

/* not public */ class BHelper {
    /* not public */ static void other() {
        //doSomething();
        System.out.println("other");
    }
}

This even works if the implementation needs the actual B instance as you may pass it as a parameter.

public interface B extends A {
    @Override
    public default void doSomething(){
        System.out.println("B");

        BHelper.other(this);
    }
    default public void other(){
        BHelper.other(this);
    }
}

/* not public */ class BHelper {
    /* not public */ static void other(B instance) {
        //doSomething();
        System.out.println("other");
    }
}

Upvotes: 4

Related Questions