Java 8 interface changes include static methods and default methods in interfaces. Prior to Java 8, we could have only method declarations in the interfaces. But from Java 8, we can have default methods and static methods in the interfaces.
Designing interfaces have always been a tough job because if we want to add additional methods in the interfaces, it will require change in all the implementing classes. As interface grows old, the number of classes implementing it might grow to an extent that it’s not possible to extend interfaces. That’s why when designing an application, most of the frameworks provide a base implementation class and then we extend it and override methods that are applicable for our application. Let’s look into the default interface methods and static interface methods and the reasoning of their introduction in Java 8 interface changes.
For creating a default method in java interface, we need to use “default” keyword with the method signature. For example,
package com.journaldev.java8.defaultmethod;
public interface Interface1 {
void method1(String str);
default void log(String str){
System.out.println("I1 logging::"+str);
}
}
Notice that log(String str) is the default method in the Interface1
. Now when a class will implement Interface1, it is not mandatory to provide implementation for default methods of interface. This feature will help us in extending interfaces with additional methods, all we need is to provide a default implementation. Let’s say we have another interface with following methods:
package com.journaldev.java8.defaultmethod;
public interface Interface2 {
void method2();
default void log(String str){
System.out.println("I2 logging::"+str);
}
}
We know that Java doesn’t allow us to extend multiple classes because it will result in the “Diamond Problem” where compiler can’t decide which superclass method to use. With the default methods, the diamond problem would arise for interfaces too. Because if a class is implementing both Interface1
and Interface2
and doesn’t implement the common default method, compiler can’t decide which one to chose. Extending multiple interfaces are an integral part of Java, you will find it in the core java classes as well as in most of the enterprise application and frameworks. So to make sure, this problem won’t occur in interfaces, it’s made mandatory to provide implementation for common default methods of interfaces. So if a class is implementing both the above interfaces, it will have to provide implementation for log()
method otherwise compiler will throw compile time error. A simple class that is implementing both Interface1
and Interface2
will be:
package com.journaldev.java8.defaultmethod;
public class MyClass implements Interface1, Interface2 {
@Override
public void method2() {
}
@Override
public void method1(String str) {
}
@Override
public void log(String str){
System.out.println("MyClass logging::"+str);
Interface1.print("abc");
}
}
Important points about java interface default methods:
java.lang.Object
. The reasoning is very simple, it’s because Object is the base class for all the java classes. So even if we have Object class methods defined as default methods in interfaces, it will be useless because Object class method will always be used. That’s why to avoid confusion, we can’t have default methods that are overriding Object class methods.Java interface static method is similar to default method except that we can’t override them in the implementation classes. This feature helps us in avoiding undesired results incase of poor implementation in implementation classes. Let’s look into this with a simple example.
package com.journaldev.java8.staticmethod;
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
Now let’s see an implementation class that is having isNull() method with poor implementation.
package com.journaldev.java8.staticmethod;
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
Note that isNull(String str)
is a simple class method, it’s not overriding the interface method. For example, if we will add @Override annotation to the isNull() method, it will result in compiler error. Now when we will run the application, we get following output.
Interface Null Check
Impl Null Check
If we make the interface method from static to default, we will get following output.
Impl Null Check
MyData Print::
Impl Null Check
Java interface static method is visible to interface methods only, if we remove the isNull() method from the MyDataImpl
class, we won’t be able to use it for the MyDataImpl
object. However like other static methods, we can use interface static methods using class name. For example, a valid statement will be:
boolean result = MyData.isNull("abc");
Important points about java interface static method:
Before I conclude the post, I would like to provide a brief introduction to Functional interfaces. An interface with exactly one abstract method is known as Functional Interface. A new annotation @FunctionalInterface has been introduced to mark an interface as Functional Interface. @FunctionalInterface annotation is a facility to avoid accidental addition of abstract methods in the functional interfaces. It’s optional but good practice to use it. Functional interfaces are long awaited and much sought out feature of Java 8 because it enables us to use lambda expressions to instantiate them. A new package java.util.function
with bunch of functional interfaces are added to provide target types for lambda expressions and method references. We will look into functional interfaces and lambda expressions in the future posts.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
great tutorials cleatly explains the concept without deviating from the topic. Awaiting for your future posts on functional interfaces and lambda expressions.
- Dilip Kumar Pandey
Superb explanation , we are awaited for next post .
- Ranjith
I like the new static interface methods feature, but I don’t think what you suggested here is a good idea - an interface is meant to be implemented, to expand the protocol of an object, whereas utility classes such as Collections are just containers for utility functions, which is a bit of a hack, as Java does not provide support for standalone functions. I think classes are a better choice. Given the newfound power of interfaces, we should leave them for what they are meant for, to define partial protocols (and implementations) for objects in an object-oriented program, and continue to use classes as a pattern for holding non-OO functionality. is that better than using classes?
- Rafael Chaves
Very nice explanation…Thanks…
- Pramodkumar
With interface default methods there may also be a scenario where an interface is extending another interface and both of those interfaces have same default method.
- Anshudeep
Very good explanation indeed ! ! One very minor observation : In the class Interface1, line 9 -> is the print(str) a typo ? Thanks !
- DRC
Could you please explain how this got printed if we remove static from the interface method MyData Print::
- Tejasvi
Excellent explanation and useful replies. Thanks Pankaj for your blog entries! I suggest we replace line 8 of the MyDataImpl class to the shorter version shown below. It is more concise and common usage, while providing the same result as the current version. Thanks! return str == null;
- JJ
hi, indeed i would also like to know what is with that print from line 9, Interface1, default method. Thanks in advance. regards
- Paula
Hi Pankaj - Thanks for such a concise and self-explanatory blogpost. Quick question - I am trying to understand why is it that Functional Interfaces can have ONLY one method ? Why not overloaded methods ? For example - operate(int a, int b) operate(float a, float b)
- IRS