Ernest Duodu Ernest is a Java developer. Outside programming, he also enjoys a wide variety of hobbies which includes sky-diving, photography, exercising and listening to music.

Are you a Java Developer working with PDF files?

Find out why you should be using JPedal

Java 8 Default Methods Explained in 5 minutes

2 min read

At IDR Solutions we use Java 8 for the development of our products (a Java PDF Viewer and SDKPDF to HTML5 converter and a Java ImageIO replacement).

In this article, we will be looking at Defaults Methods which is another really useful feature of Java 8.

Default methods enable us to add new functionalities to interfaces without breaking the classes that implement that interface. Let’s take a look at the example below.

public class MyClass implements InterfaceA {

    /**
     * @param args the command line arguments
     */    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }
   
}

interface InterfaceA {
  public void saySomething(); 
  
}

The code above shows the class MyClass implementing InterfaceA’s method saySomething(). Now, let’s add a new method called sayHi() InterfaceA. By doing so, we have introduced a problem to class MyClass as it will not compile until we provide an implementation for the method sayHi().
This is when Defaults methods becomes useful. By Adding the keyword default before the method’s access modifier, we do not have to provide an implementation for the method sayHi() in class MyClass.

In ‘the strictest sense’, Default methods are a step backward because they allow you to ‘pollute’ your interfaces with code. But they provide the most elegant and practical way to allow backward compatibility. It made it much easier for Oracle to update all the Collections classes and for you to retrofit your existing code for Lambda.

public class MyClass implements InterfaceA {

    /**
     * @param args the command line arguments
     */    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
      System.out.println("Hi");
    }

}

Note that we have to provide an implementation for all default methods. So default methods provide us the flexibility to allow methods to be implemented in interfaces. The implementation will be used as default if a concrete class does not provide an implementation for that method.

Conflicts with Multiple Interface.

Since classes in java can implement multiple interfaces, there could be a situation where 2 or more interfaces have a default method with the same signature hence causing conflicts as java will not know what methods to use at a time. This will then result in a compilation error with the message MyClass inherits unrelated defaults for sayHi() from types InterfaceA and InterfaceB
Let’s take a look at the example below.

public class MyClass implements InterfaceA, InterfaceB {

    /**
     * @param args the command line arguments
     */    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
        System.out.println("Hi from InterfaceA");
    }

}

interface InterfaceB {
     default public void sayHi() {
        System.out.println("Hi from InterfaceB");
    }
}

In order to work around situations like this, we will have to provide an implementation for sayHi() method in the class MyClass therefore overriding both methods in InterfaceA and InterfaceB.

public class MyClass implements InterfaceA, InterfaceB {

    /**
     * @param args the command line arguments
     */    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }
    
    @Override
    public void sayHi() {
        System.out.println("implemetation of sayHi() in MyClass");
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
        System.out.println("Hi from InterfaceA");
    }

}

interface InterfaceB {
     default public void sayHi() {
        System.out.println("Hi from InterfaceB");
    }
}

If we want to specifically invoke one of the sayHi() methods in either InterfaceA or InterfaceB, we can also do as follows:

public class MyClass implements InterfaceA, InterfaceB {

    /**
     * @param args the command line arguments
     */    public static void main(String[] args) {
        // TODO code application logic here
    }

    @Override
    public void saySomething() {
        System.out.println("Hello World");
    }
    
    @Override
    public void sayHi() {
       InterfaceA.super.sayHi();
    }

}

interface InterfaceA {

    public void saySomething();

    default public void sayHi() {
        System.out.println("Hi from InterfaceA");
    }

}

interface InterfaceB {
     default public void sayHi() {
        System.out.println("Hi from InterfaceB");
    }
}

If you found this article useful, you may also be interested in our other Java8 posts on Lambda Expression, Streams API, Consumer Suppliers, Method References, Optional and Repeating Annotations.

We also now have a large collection of articles on what is new in other versions of Java, including Java9, and Java12.



Our software libraries allow you to

Convert PDF to HTML in Java
Convert PDF Forms to HTML5 in Java
Convert PDF Documents to an image in Java
Work with PDF Documents in Java
Read and Write AVIF, HEIC, WEBP and other image formats
Ernest Duodu Ernest is a Java developer. Outside programming, he also enjoys a wide variety of hobbies which includes sky-diving, photography, exercising and listening to music.

20 Replies to “Java 8 Default Methods Explained in 5 minutes”

  1. Thanks! This is a pretty good, digestible runthrough of default methods. I’m not too crazy about them but at least now I understand how they work 😀

  2. Wow this is exciting stuff. I think public updates for Java 7 are ending so we might have to migrate to Java 8. Learning features a little at a time. First lambda, then streams, now this. Exciting times!

    1. well,a class can only extends one abscract class,but a class can implements more than one interface.That’s the difficult,help this can solve your problem

  3. With Java 8 new feature , “Default Methods ” They give this feature for ensuring backward compatibility . But now with is ,what is the main difference between interface and abstract class? Now both are same , am i right?

    1. Himanshu, they are not the same, default methods are there to add external functionality to existing classes without changing their state and also you can have a constructor in an abstract class but not in an interface.

  4. Thanks, very clear … I just found out about this feature… but I find it a bit crazy that they haven’t gone the whole way and simply allowed multiple inheritance of classes: I’ve always felt that the “Diamond problem” is not a massive problem, since the compiler can do what it does here: insist that the subclass resolve the ambiguity. Now you can have a “default method” but you can’t have a “default field”. Unsatisfactory.

  5. Nice article, clear and precise!

    IMHO default methods introduce in Java something that is like what they tried to avoid in the first place: multiple abstract classes inheritance!
    I wouldn’t use default methods if not really necessary.

  6. This is an excellente article! I was a reading a book but didn’t understand till I read your blog.
    Thanks.

  7. Found your article through DuckDuckGo when I came across default methods for the first time in class. I wish our professor was this clear and easy to understand. Thanks for writing this :).

Comments are closed.