Card 05/ 08
Default Methods in Java Interfaces
Java 8 needed to add forEach to every collection without breaking millions of classes nobody could edit.
A default method is a method in an interface with a body, marked default. Classes that implement the interface inherit it and may override it. It exists so an interface can gain a method without breaking the classes that already implement it.
Java 8 wanted to add forEach to Iterable, and through it to every List. Adding a method to an interface used to break every class implementing it, and there were millions of them in code nobody at Oracle could edit. A default method arrives with a body, so existing classes keep compiling:
interface Archivable {
String archiveKey();
LocalDate archivedOn();
default boolean isExpired() {
return archivedOn().isBefore(LocalDate.now().minusYears(7));
}
}The default body may only use the interface's own methods, because an interface still has no fields to read. That is the line between a default method and an abstract class, a partly written class that can hold fields, and it has not moved.
| Kind | Has a body | Overridable | Since |
|---|---|---|---|
| Abstract | No | Must be implemented | Java 1 |
default | Yes | Yes | Java 8 |
static | Yes | No: called on the interface name | Java 8 |
private | Yes | No: a helper for the two above | Java 9 |
So an interface can now carry behaviour without carrying data, which is what lets it grow without breaking its implementations. Use it for that, a default most classes want, rather than as a way to avoid writing an abstract class.
← → move through sections and cards