2020-03-07

Lambda expressions - Default interface methods

Default interface methods

The introduction of default methods is trying to solve a longstanding problem in Java interface
design: how to evolve a published interface. Java’s interface is a very tight contract between an API and its client. Before Java 8, once an interface is published and implemented by other clients,
it’s very hard to add a new method to the interface without breaking existing implementations. All
implementations must be updated to implement the new method. This means interface design has
to be done correctly at the first time and cannot happen iteratively without breaking existing code.

Before Java 8, an interface can only have abstract methods. Abstract methods must be implemented
by implementation classes. Default methods of interfaces in Java 8 can have both declarations and
implementations. Implementation of a default method will be inherited by classes which don’t
override it. If we want to add a new method to an existing interface, this new method can have
default implementation. Then existing code won’t break because this new method will use the
default implementation. New code can override this default implementation to provide a better
solution. In the default method’s implementation, only existing interface methods can be used.

A simple example about how to use default interface methods. The scenario is to insert
records into a database.

public interface RecordInserter {
void insert(Record record);
}

First implementation of RecordInserter interface
public class SimpleRecordInserter implements RecordInserter {
@Override
public void insert(Record record) {
System.out.println("Inserting " + record);
}
}


Then we find out that the performance of inserting a lot of records is not very good, so we want
to add batch inserting to improve performance. So a new method insertBatch is added to the
RecordInserter interface with default implementation. insertBatch takes a list of Record as input,
so the default implementation just iterates the list and uses existing insert method to insert Record
one by one. This default implementation can make sure SimpleRecordInserter class still works.

RecordInserter interface with batch insert
public interface RecordInserter {
void insert(Record record);
default void insertBatch(List<Record> recordList) {
recordList.forEach(this::insert);
}
}
New implementation of insertBatch method
public class FastRecordInserter extends SimpleRecordInserter {
@Override
public void insertBatch(List<Record> recordList) {
System.out.println("Inserting " + recordList);
//Use SQL batch operations to insert
}
}

Static interface methods

In Java 8, interfaces can also have static methods. Helper methods related to an interface can be
added as static methods.

public interface WithStaticMethod {
static void simpleMethod() {
System.out.println("Hello World!");
}
}


No comments:

Post a Comment