What was the design consideration of not allowing use-site injection of extension methods to java 8?

This was driven by a philosophical belief: API designers should control their APIs. While externally injecting methods into APIs is surely convenient, it undermines an API designers control over their API. (This is sometimes called "monkey-patching".)

On the terminology: what C# calls "extension methods" is merely one form of extension method, not the definition of extension method; Java's default methods are also extension methods. The main differences are: C# extension methods are static and are injected at the use-site; Java's are virtual and declaration-site. Secondarily, C# extension methods are injected into types, whereas Java's default methods are members of classes. (This allows you to inject a sum() method into List<int> in C# without affecting other List instantiations.)

It's natural, if you have gotten used to the C# approach, to assume that this is the "right" or "normal" or "real" way to do it, but really, it's just one of many possible ways. As other posters have indicated, C# extension methods have some very serious drawbacks compared to Java's default methods (for example, poor reflective discoverability, poor discoverability through documentation, not overrideable, require ad-hoc conflict-management rules). So the Java glass is well more than half-full here by comparison.


While Brian Goetz mentions that default methods will also be used for convenience, it does not mean that it was the first goal of default methods.

As a reminder: default methods exist in order to support interface evolution, something that was extremely badly needed in the face of the introduction of lambdas (as the introduction of lambda-using methods often meant that new methods should be added).

You are writing your post as if there was no drawback to extension methods as they exist in C#, however:

  • Extension methods have an enormous discoverability issue:

    • They do not appear in the class documentation;
    • They are not exposed by reflecting over the class;
    • When you see a usage of an extension method in code, you have no way of knowing where the extension method comes from without an IDE;
  • Extension methods, by their very nature, do not allow some of the standard disambiguation mechanisms:

    • What happens when you use an extension method to define an overload for a class method, and that overload, or a similar extension method, is defined by the author of the class? Case 1: Your code switches over to using the new method with a simple recompilation; Case 2: Your code does not compile anymore;
    • Because of that, I do not recommend defining putting extension methods in a namespace that you do not control, as it can make such issues intractable. However, doing that means that extension methods for types you do not control become even harder to discover;
  • Extension methods are inflexible:

    • Once an extension method is defined by a library, there is no way for clients of that library to change or tweak that extension method's implementation;
    • If a client defines an extension method for a type he does not control, he will have a compatibility issue on his arms the day that the library defines the same extension method. The likelihood of that depends on what the extension method does, and the evolution policy of that library.

Of these three drawbacks, default methods as they exist in Java 8 have none of them.

You should note that, the big reason for the inclusion of extension methods in C# was to enable LINQ. As Java went with another design for its streams, I do not see the Java language designers adding them as a matter of course.