Is it a feature abuse to introduce default methods in new interfaces?
brian.goetz at oracle.com
Sat Feb 23 14:00:16 UTC 2019
Here’s an authoritative answer: it depends :)
More seriously, while the proximate motivation for adding default methods to Java was to ease the evolution of already-published APIs, there are plenty of good reasons to use it in new code as well. (However, there are also some possible abuses.)
I addressed a similar question in this post (relevant excerpts quoted below):
A key design goal was that, from the perspective of the client of an interface, default methods should be indistinguishable from "regular" interface methods. The default-ness of a method, therefore, is only interesting to the designer and implementor of the interface.
Here are some use cases that are well within the design goals:
• Interface evolution. Here, we are adding a new method to an existing interface, which has a sensible default implementation in terms of existing methods on that interface. An example would be adding the forEach method to Collection, where the default implementation is written in terms of the iterator() method.
• "Optional" methods. Here, the designer of an interface is saying "Implementors need not implement this method if they are willing to live with the limitations in functionality that entails". For example, Iterator.remove was given a default which throws UnsupportedOperationException; since the vast majority of implementations of Iterator have this behavior anyway, the default makes this method essentially optional. (If the behavior from AbstractCollection were expressed as defaults on Collection, we might do the same for the mutative methods.)
• Convenience methods. These are methods that are strictly for convenience, again generally implemented in terms of non-default methods on the class. (Usually these methods are similar to existing non-default methods, but have fewer arguments.)
• Combinators. These are compositional methods that instantiate new instances of the interface based on the current instance. For example, the methods Predicate.and() or Comparator.thenComparing() are examples of combinators.
If you provide a default implementation, you should also provide some specification for the default (in the JDK, we use the @implSpec javadoc tag for this) to aid implementors in understanding whether they want to override the method or not. Some defaults, like convenience methods and combinators, are almost never overridden; others, like optional methods, are often overridden. You need to provide enough specification (not just documentation) about what the default promises to do, so the implementor can make a sensible decision about whether they need to override it.
> On Feb 21, 2019, at 9:35 AM, Jaikiran Pai <jai.forums2013 at gmail.com> wrote:
> I have been trying to find some authoritative answer on when _not_ to
> use default methods on interfaces (a feature introduced in Java 8). The
> official documentation in Java, about this feature, talks about the
> motivation behind introducing this feature and explains how
> _existing_ interfaces can be changed to add default methods without
> breaking binary compatibility:
> "Default methods enable you to add new functionality to the interfaces
> of your libraries and ensure binary compatibility with code written for
> older versions of those interfaces."
> This and some other docs don't mention whether it's an accepted practice
> or abuse of default methods feature, when dealing with new interfaces.
> Is it fine to introduce new interfaces with default methods? I have
> tried searching the mailing list archives to see if it's discussed
> previously but my search terms haven't found anything relevant. Any
> previous authoritative answer, similar to Stuart Mark's reply on
> stackoverflow (on a different topic) about Optional usage, is also
> good enough.
>  https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
More information about the jdk-dev