Java 'default' methods, future problem?

Java 'default' methods, future problem?

In Java there is one golden rule, we don’t break backwards compatibility. Not in the JVM interpreter/compiler and not in the JDK classes.

Extending interfaces

With the introduction of Lambda’s in Java there was a suddenly a big need to extend some of the Collections interfaces. And this is something that breaks backwards compatibility. If Java wants to add List.forEach all custom implementations of the List interface won’t compile anymore. This breaks one of the most treasured rules in JDK development, the backwards compatibility.

default

To counter this the ‘default’ keyword is introduced. Just like an abstract method in an abstract class you can now add some default behaviour to interfaces. This means for example that the List interface can be extended with default logic which can be overwritten (but doesn’t have to be). For example, see the following new ‘default’ method from the Iterable interface:

default void forEach(Consumer<? super T> action) {
	Objects.requireNonNull(action);
	for (T t : this) {
    	action.accept(t);
	}
}

There are some important rules; the added code will operate on static data, it can’t and should never manipulate state!
Some more info, examples and other solutions can be found here.

Possible future problems…

There is a new problem that will become larger once there are more and more extentions as default methods. There is a possibility of colliding default methods. This will still break backwards compatibility. For example the List interface and the Set interface both have:

default Spliterator<E> spliterator()

Now (crazy example) I’ve made something called MyListSet which implements all methods from List and also all methods from Set. This compiles fine in every Java version but will suddenly fail against Java 1.8. Both List and Set have the same spilerator() on the same level and will thus collide with the following exception:

class MyListSet<T> inherits unrelated defaults for spliterator() from types Set and List
  where T is a type-variable:
    T extends Object declared in class MyListSet

The more these ‘default’ methods are going to be used the higher the chance collisions like this will break backwards compatibility in the future. Personally I’m not yet convinced about the default methods.