Proposal for extending functionality of default methods to allow general use

Brian Goetz brian.goetz at oracle.com
Wed Jan 30 13:07:32 PST 2013


tl;dr version: No.


This is ground that was covered a long time ago.  Let me first compare 
with C# since this is a most proximate example of use-site extension 
methods.

Our extension methods are /declaration-site/ and /virtual/.  By 
contrast, C# extension methods are /use-site/ and /static/.  Further, 
our extension methods are added to /classes/, whereas C# extension 
methods are added to /types/.

There are some benefits to each; C# users are jealous of the 
virtual-ness of our extension methods, and Java developers will be 
jealous when they realize that you can't add a sum() method to 
List<Integer> without adding it to all Lists.  But the issue you raise 
-- being able to monkey-patch new methods into someone else's classes -- 
is not a clear winner in either direction.

Your argument seems to be "use site extension seems really convenient." 
  I don't dispute the convenience of this, and C# has done some 
impressive things with their extension methods (reified generics 
helped).  However, our decision was a principled decision -- API 
developers should own their APIs, for better or worse.

Allowing use-site extension also undermines virtualness, which is also 
tremendously valuable.  Given how much nastiness has its root in 
staticness, do we want to add a language mechanism that engenders more 
staticness?  Nope.

Now, your proposal is not exactly like C#'s.  While it is short on 
detail, it appears to be quite similar to the "Expanders" paper by 
Milstein et al: http://www.cs.ucla.edu/~todd/research/oopsla06a.pdf. 
This was one of the many models we explored before settling on the 
current one.


On 1/30/2013 3:33 PM, Lattie wrote:
> Currently default methods can be used by the author of an Interface to
> extend the functionality of that Interface without requiring the
> rewriting of code that already implements that Interface.
>
> That's a great feature, but it would be even greater if end-user
> programmers were enabled to extend the functionality of existing
> Interfaces.  (As it is, the feature is to be used by the *authors* of
> Interfaces, but not by the *users* of the Interfaces.)
>
> This can be accomplished as follows:
>
> 1) Introduce the concept of an 'Extension Interface', which is an
> Interface that derives from an existing interface, and then *only*
> adds 'default' methods.
>
> 2) Allow the casting of an object that implements a given Interface
> into an instance of any 'Extension Interface' derived from the
> original Interface.
>
> This would allow end users to express additional desired behavior for
> existing libraries in a simple, intuitive and straightforward way.  It
> does not require any changes to the Java language syntax, only the
> recognition by compilers that casting an object into an Extension
> Interface type is ok to do.
>
> For example, consider the following code:
>
> ### MyExtendedList.java
>
> import java.util.*;
>
> // This is an 'Extension Interface' of List<T>
> public interface MyExtendedList<T> extends List<T>
> {
>     default void printSize()
>     {
>        System.out.println("The size of this list is: " + size());
>     }
> }
>
> ### Test.java
>
> import java.util.*;
>
> public class Test
> {
>     public static void main(String[] args)
>     {
>        List<String> strings = new ArrayList<>();
>
>        strings.add("foo");
>        strings.add("bar");
>
>        MyExtendedList<String> myStrings = (MyExtendedList<String>)strings;
>
>        myStrings.printSize();
>     }
> }
>
> ######
>
> With the proposed extension, this code would print out:
>
> The size of this list is: 2
>
> As it is, an exception is thrown:
>
> Exception in thread "main" java.lang.ClassCastException:
> java.util.ArrayList cannot be cast to MyExtendedList
>
> The reason it would always be safe to allow the cast to succeed is
> that any 'Extension Interface' is always defined only in terms of the
> already existing public interface methods that exist on the Interface
> from which it derives.
>
> Another way to look at it is that any object that implements a given
> Interface also *implicitly* implements any and all 'Extension
> Interfaces' that are based on the original Interface.  Under this
> view, even the cast could be eliminated and the object assigned
> directly.
>
> The benefits to end user programmers of adding this new ability to
> effectively extend the behavior of existing classes simply by casting
> them would be profound, and most welcome.
>
> Since no changes to the language are required, there would be no
> adverse impact on those not wishing to make use of the feature.
>


More information about the lambda-dev mailing list