Default, Static and Private Methods in Java Interfaces

Which Java JDK to use? Image of different cups of coffee

We already know that a Java interface specifies a set of required behaviours which we can implement appropriately in any number of possibly unrelated classes. Using interfaces we can also simulate multiple inheritance (after a fashion).

In Java, an interface is written in the same way as a class, with the keyword interface replacing the keyword class. There are key differences, however. Interfaces have no instance data fields and up to Java 8, only have method headers with no code implementations.

From Java 8, interfaces can contain default and static method implementations. From Java 9, interfaces can also contain private method implementations.

Default Methods

Adding a new method to an existing interface can create many problems. Existing classes implementing that interface need to be changed to provide an implementation for the new method.

This is the rationale behind default methods in interfaces: they let classes automatically inherit a default implementation from an interface. Default methods are also called defender methods. They defend class implementations against interface changes.

Default instance methods provide a way to evolve interfaces without breaking existing implementations. The classes implementing the new versions of the interface are not forced to implement the default methods. However, they can override them if required.

We mark default methods with the default keyword as a modifier:

public interface MyInterface {

    // abstract methods as usual
    public void foo();
    public void bar(int a);

    // method with a default code implementation
    public default void baz(int b) {
        // some appropriate code...
    }
}

Section §9.4 of the Java Language Specification (JLS) contains extra details on method declarations. An extract follows:

A default method is an instance method declared in an interface with the default modifier. Its body is always represented by a block, which provides a default implementation for any class that implements the interface without overriding the method. Default methods are distinct from concrete methods (§8.4.3.1), which are declared in classes, and from private interface methods, which are neither inherited nor overridden.

A good example of the use of default interface methods is in the java.util.Collection interface. Streams were introduced in Java SE8. A collection is one of the possible sources for a stream. The default stream() and parallelStream() methods were added to the Collection interface to create streams. Because these methods contained default code implementations, the updated interface did not break any existing classes that implemented the Collection interface.

Adding too many default methods to an interface is not a good design. It should only be done to avoid breaking any backward compatibility when upgrading existing interfaces.

Private Methods

From Java SE9 we can now define private methods in an interface in the same way that we define them in a class. We use these methods for private internal code. They are only accessible inside the interface. They cannot be accessed or inherited by another interface or class.

public interface MyInterface {

    // abstract methods
    public void foo();
    public void bar(int a);

    // default method with code implementation
    public default void baz(int b) {
        // some code...
        qux();  // calling a private method
        // some more code...
    }

    // private method
    private void qux() {
        // even more code...
    }
}

Static Methods

In the same way we can define default methods in an interface, we can define static methods. These methods do not need an object that implements the interface, but can be run directly from the class as is usual with static methods.

public interface MyInterface {

    // abstract methods
    public void foo();
    public void bar(int a);

    // default method with code implementation
    public default void baz(int b) {
        // some appropriate code...
    }

    // static method
    public static void waldo() {
        // appropriate class code...
    }}

Section §9.4 of the JLS contains extra details. A few paragraphs follow:

An interface can declare static methods, which are invoked without reference to a particular object. Static interface methods are distinct from default methods, abstract interface methods, and non-static private interface methods, all of which are instance methods.

The declaration of a static interface method introduces a static context (§8.1.3), which limits the use of constructs that refer to the current object. Notably, the keywords this and super are prohibited in a static context (§15.8.3, §15.11.2), as are unqualified references to instance variables, instance methods, and type parameters of lexically enclosing declarations (§6.5.5.1, §6.5.6.1, §15.12.3).

A common pattern is to define an interface and a companion utility class that defines static methods that operate on instances of that interface. For example, Collection is an interface, and Collections is a companion class that manipulates Collection objects. The Collections class consists exclusively of static methods that operate on collections. Now that static methods can be written inside interfaces, these utility classes could be removed, and their static methods moved inside the interface. Obviously in the case of standard classes like Collections, these companion classes will remain in the Java API for backward compatibility.

Metasyntactic Variables

Now for something lighter, and just out of interest…

Have you even wondered why lots of programming books and articles use foo bar, baz and other equally strange names? These are called metasyntactic variables. They are used as placeholders for proper variable names in computer programming.

Commonly used names include foobar, foo, bar, baz, qux, quux, corge, grault, garply, waldo, fred, plugh, xyzzy, and thud. A number of these names are references to the text-based adventure game Colossal Cave Adventure, released in 1976 on the PDP-10 computer.

Signing Off

Was this interesting? Please share your comments, and as always, stay safe and keep learning!

Leave a Comment

Your email address will not be published. Required fields are marked *

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.