Java 8 Static Methods vs Default Methods in Interfaces

This article explains Java 8 Static Methods and Default Methods in Interfaces w.r.t to their various aspects with examples. An important point to understand before we start looking at static and default methods in interfaces is that they are not an either/or options. Its not like you have to choose one of them to implement. On the contrary, static and default methods work together to deliver the full functionality of an interface.

Quick Introductions to Static & Default Methods
What are Static Methods: These are methods written in Interfaces which are static. Till Java 7, static methods were only allowed on Classes. Beginning Java 8 static methods are now allowed in Interfaces as well.
Static methods in interfaces are accessible through the interface name like this –
<Interface-Name>.<Static-Method-Name>.
For example:java.util.Predicate Interface has a static method isEqual() which can be accessed like this Predicate.isEqual().
Note – This is same as the way static methods are accessed on a Class.

What are Default Methods: These are methods written in Interfaces, indicated by the modifier default. As their name suggests these methods are available by default to all the classes which implement this interface. In case you are not familar with default methods, please refer the detailed article I have written on them here – default methods tutorialTutorial on Java 8 Default Methods.

Java 8 Static Methods vs Default Methods in Interfaces
Listed below are the main diftferences in the way static and default methods are used in interfaces –
Difference 1 – Definition in code\usage
Lets see how static and default methods are defined in code with an example –

Java 8 code showing static and default methods' definition
//InterfaceWithDefaultStatic.java
public interface InterfaceWithDefaultStatic {
    public static void staticMethod() {
        System.out.println("Static Method's print");
    }
    public default void defaultMethod() {
        System.out.println("Static Method's print");
    }
}
A static method is defined similar to the way a static variable or method is defined in classes
<access modifier> static <return-parameter> method-name([<method-params>])[throws <Exceptions>]
Example: public static void staticMethod()

A default method is defined in a very similar way except that instead of static keyword, the default keyword is used
<access modifier> default <return-parameter> method-name([<method-params>])[throws <Exceptions>]
Example: public default void defaultMethod()

Difference 2 – Scope for method invocation
A static method is visible/usable in Interface Scope. Once the interface has been compiled, then the static method can be invoked as –
<Interface-Name>.<static-method-name>([params])
For Example: For the code shown in difference-1 above, staticMethod() would be invoked as – InterfaceWithDefaultStatic.staticMethod()

A default method is visible\usable in the object instance scope. A Class needs to implement the interface containing the default method, then the default method can be invoked on the instance of the implementing class. The format of invocation of a default method is –
<ObjectInstance-name>.<default-method-name>([params])
For Example: Lets say there is a class named DefaultImpl as shown below –

DefaultImpl.java
public class DefaultImpl implements InterfaceWithDefaultStatic{
//class contents
}

For the above class DefaultImpl, to invoke the default method we will have to create an instance of the class, and then invoke it like this –

Invocation of default method of DefaultImpl.java
DefaultImpl defaultImplInstance=new DefaultImpl();
defaultImplInstance.defaultMethod();

Difference 3 – Purpose served in the overall design
When to design\use Static Methods: Static Methods are the utility(util) methods which are associated to an Interface. So, in case you need any util methods which can operate on an Interface’s implementing class’s instances, then add that as a static method to the Interface itself.

Until Java 7, the general practice was to have such util methods in a separate utility class which contains all the static methods which can be invoked on an interface’s implementation’s instance.
For example: Collections class has a sort method –
static <T> void sort(List<T> list, Comparator<? super T> c).
This is how any list was sorted till Java 7. The sorting util methods is present in the Collections Class as a static method.

From Java 8 onwards, since Interfaces can have static methods, it makes the design more cohesive by keeping these static util methods inside List itself. The Java designers also thought of the same and added a static method sort() to List –
default void sort(Comparator<? super E> c)
To summarize, whenever you need a static utility method for interface’s implementors, add that static utility method in Interface itself as a static method.

When to design\use Default Methods: Default methods are used when a feature is added to an existing hierarchy of classes which is not needed for the whole hierarchy.In that case, making that method an abstract method makes it mandatory for all the classes in the hierarchy to implement. This is an unnecessary overhead and a maintenance nightmare.
In this scenario, it is much simpler to add that method as a default method so that any Interface implementation which wants to use it can do so and the rest of the implementations can just ignore it. In effect making the functionality implemented through default methods an optional feature rather than a mandatory one.

Summary
In the above article we looked at the basics of the new static and default methods in interfaces. Then we looked at the key differences in their usage from syntax, scope and design angles.

 

Digiprove sealCopyright © 2014-2016 JavaBrahman.com, all rights reserved.