Introduction

Default methods in Java 8 also known as defender methods allow Java developers to add new methods to the existing interfaces in their code without breaking their current implementation. We will be further discussing all the frequently asked questions about working and using default methods in Java 8.

Default methods in Java 8

The default methods were primarily introduced to resolve compatibility issues in Java. Before default methods in Java 8, interfaces could only have abstract methods. Developers had to provide the implementation of these methods in a separate class.

So, if a developer wanted to add a new method to an interface, then the implementation code must be provided in the class that is implementing the interface. To cater to this issue, default methods allow the interfaces to have methods with implementation without affecting the classes that implement the interface.

The default methods have a body and default modifier that distinguishes them from a regular method. The default modifier is mandatory if you want to put a default method in an interface. Below mentioned code demonstrates an example of using an abstract method and a default method,

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

interface Interface01

{

// abstract method

public void printNumber(int number);

 

// default method

default void outputMsg()

{

System.out.println(“Default Method is Executed”);

}

}

 

class Class01 implements Interface01

{

// implementation of the abstract method

// no implementation required for the default method

public void printNumber(int number)

{

System.out.println(number);

}

 

public static void main(String args[])

{

Class01 obj01 = new Class01();

// abstract method is called

Obj01.printnumber(333);

// default method is called

Obj01.outputMsg();

}

The code will present the following output:

333

Default Method is Executed

Why default methods were introduced?

Although default methods in Java 8 provide a feature of having concrete methods in interfaces, it is not an improvement, but can be considered as a long due correction in Java. when some of the core APIs were being written at Java, the developers used Interfaces to define API interfaces like Java Collections API. Hence, the majority of the interfaces in collections API are Java Interfaces.

Later, with the introduction of Java 8 Streams, developers behind Java wanted to modify collections API to provide support for streams. However, if you want to add new methods in a Java Interface, it has to be implemented. They also aimed to provide backward compatibility by providing support for pre-existing implementations of List or Map during version upgrades.

See Also: When To Use The Parallel Stream In Java

To achieve both of these objectives, developers working at Java brought in the concept of default methods in Interfaces. now, the implementations can decide whether to implement a method or to use the default implementation.

Why do we need to implement a default method within the interface?

Consider a scenario where you have an interface that has multiple methods, and various classes are implementing this interface. Introducing a default method simplifies it because the implementation would be common for all classes.

In another scenario where you need to fulfill a new requirement, you will have to add a new method to an existing interface. Adding a new method will require implementing it throughout the implementation classes. By using the Java 8 default method you can easily add a default method that will not require to add its implementation in any other classes.

How to deal with multiple inheritance?

Since classes are allowed to implement multiple interfaces in Java, this arises a question regarding multiple inheritances. What if a class implements two or more interfaces and all of those interfaces define the same default methods?

Let’s see an example to demonstrate this situation:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

public interface interface01 {

default void defMethod(){

System.out.println(“Calling defMethod in interface01()”);

}

}

 

public interface interface02 {

default void defMethod(){

System.out.println(“Calling defmethod in interface02”);

}

}

 

public class Class01 implements interface01, interface02

{

}

This code will fail to compile with the following output:

java: class Class01 inherits unrelated defaults for defMethod() from types 
interface01 and interface02

It is due to the conflict caused by multiple interface inheritance commonly known as the diamond problem. If the class inherits both sets of default methods. Which ones should be called then?

To fix that error, it must be resolved in class01 by explicitly providing the implementation for the conflicting methods:

1

2

3

4

5

public class Class01 implements interface01, interface02 {

public void defMethod(){

// custom implementation

}

}

you can also have the class01 use the default method with its interfaces using the “super” keyword. The super keyword is used as a qualifier here to invoke the overridden method in the interface.

1

2

3

4

public class Class01 implements interface01, interface02 {

public void newMethod() {

return interface01.super.defMethod();

}

Furthermore, it is also allowed to make the class use both of the default methods together like this:

1

2

3

4

@Override

public void newMethod() {

return interface01.super.defMethod() + interface02.super.defMethod();

}

Default methods invocation

Now let’s see how default methods are invoked in Java 8.

From the perspective of a code in the main class, default methods are just like virtual methods. That is why they are also known as virtual extension methods. When a single class implements an interface with a default method, the main code that invokes the default method generates an invokeinterface at the call site.

1

2

Interface01 obj01 = new Class01();

obj01.defMethod(); // invokeinterface defMethod()

But In case of the conflict due to multiple inheritances discussed before. When the default method is overridden and you want to delegate the invocation to one of the interfaces, the invokespecial is generated the implementation would be specifically called,

1

2

3

4

5

public class class01 implements interface01, interface02 {

public void defMethod(){

interface01.super.defMethod(); // invokespecial defMethod()

}

}

The invokespecial instruction is used here to invoke the interface defMethod(). This is something new in Java 8 from the bytecode point of view as usually the methods invoked via super keyword points to its parent class, and not to an interface.

Difference between default methods and abstract class

After the introduction of default methods in Java 8, it seems that interfaces and abstract classes are very similar but they both are still very much different concepts in Java. An abstract class can hold the state of an object. It can have constructors and member variables. Whereas interfaces with default methods cannot hold state and it can neither have constructors nor member variables.

You should be using an Abstract class whenever you think your class can have the state or you need to add any method in the constructor. Whereas the default methods in Java 8 are used for backward compatibility.

Whenever you need to add additional functionality to an existing legacy interface, you can use default methods without breaking any existing implementor classes. Hence, both are used for totally different purposes, and choosing between two of them fully depends on the requirements of your code.

Difference between default methods and regular methods

Apart from implementation and default modifier, the default methods in Java 8 are still quite different from the regular methods. A regular method in a class can access as well as change the method arguments and the fields of its class, on the other hand, the default methods in Java 8, can only access its arguments as the interfaces do not have any state.

How to extend the interfaces that contain default methods in Java 8

When an interface containing a default method is extended, you can do the following things:

  • You may not mention the default method, which lets your extended interface inherit the default method.
  • You can redeclare the default method, which will make it an abstract method.
  • Or you can redefine the default method, which will override it.

You can go with any of these options based on your requirement for interface extension in your code.

Final thoughts on default methods in Java 8

Default methods have been a great addition in Java 8. It has solved various existing problems in Java as well as proves to be a very useful feature for backward compatibility. Java developers can now extend the interfaces without breaking their existing implementation. We have covered some basic concepts of default methods in Java 8 throughout this article but you can explore them further as they have a range of possible uses.

Author

Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.

Write A Comment