Java 8 add extension/default method to class Java 8 add extension/default method to class java java

Java 8 add extension/default method to class


Java doesn't have extension methods. Default methods are not extension methods. Let's look at each feature.

Default methods

Both Java and C# support this feature

Problems solved:

  1. Many objects may implement the same interface and all of them may use the same implementation for a method. A base class could solve this issue but only if the interface implementors don't already have a base class as neither java nor C# support multiple inheritance.
  2. An API would like to add a method to an interface without breaking the API consumers. Adding a method with a default implementation solves this.

Java's or C#'s default methods are a feature to add a default implementation to an interface. So objects that extend an interface don't have to implement the method, they could just use the default method.

interface IA { default public int AddOne(int i) { return i + 1; } }

Any object that implements IA doesn't have to implement AddOne because there is a default method that would be used.

public class MyClass implements IA { /* No AddOne implementation needed */ } 

C# now has this feature in C# 8 (or .Net 5)

C#'s Extension Method

Problems solved:

  1. Ability to add methods to sealed classes.
  2. Ability to add methods to classes from third-party libraries without forcing inheritance.
  3. Ability to add methods to model classes in environments where methods in model classes are not allowed for convention reasons.
  4. The ability for IntelliSense to present these methods to you.

Example: The type string is a sealed class in C#. You cannot inherit from string as it is sealed. But you can add methods you can call from a string.

var a = "mystring";a.MyExtensionMethed()

Java lacks this feature and would be greatly improved by adding this feature.

Conclusion

There is nothing even similar about Java's default methods and C#'s extension method features. They are completely different and solve completely different problems.


C# extension methods are static and use-site, whereas Java's default methods are virtual and declaration-site.

What I believe you are hoping for is the ability to "monkey-patch" a method into a class you do not control, but Java does not give you that (by design; it was considered and rejected.)

Another benefit of default methods over the C# approach is that they are reflectively discoverable, and in fact from the outside, don't look any different from "regular" interface methods.

One advantage of C#'s extension methods over Java's default methods is that with C#'s reified generics, extension methods are injected into types, not classes, so you can inject a sum() method into List<int>.

Above all, the main philosophical difference between Java's default methods and C#'s extension methods is that C# lets you inject methods into types you do not control (which is surely convenient for developers), whereas Java's extension methods are a first-class part of the API in which they appear (they are declared in the interface, they are reflectively discoverable, etc.) This reflects several design principles; library developers should be able to maintain control of their APIs, and library use should be transparent -- calling method x() on type Y should mean the same thing everywhere.


C# extension methods are just syntactic sugar for static methods that take the extended type as first argument. Java default methods are something completely different. To mimic C# extension methods, just write usual static methods. You will not have the syntatic sugar, however; Java does not have this feature.

Java default methods are real virtual methods. For example, they can be overridden. Consider a class X inheriting from an interface I that declares a default foo() method. If X or any of its super classes declares no own foo() method, then X will get the foo() implementation of I. Now, a subclass Y of X can override X.foo() like a usual method. Thus, default methods are not only syntactic sugar. They are real extensions of the method overriding and inheritance mechanism that cannot be mimicked by other language features.

Default methods even require special VM support, so they are not even a compiler only feature: During class loading, the hierarchy of a class has to be checked to determine which default methods it will inherit. Thus, this decision is made at runtime, not at compile time. The cool thing about it is that you do not have to recompile a class when an interface it inherits gets a new default method: The VM will, at class load time, assign that new method to it.