PROPOSAL: Static Methods in Interfaces
Joseph D. Darcy
Joe.Darcy at Sun.COM
Tue Mar 17 15:27:19 PDT 2009
A few comments.
I generally find the helper class pattern to be an adequate workaround
to this problem.
Reinier Zwitserloot wrote:
> Apparently the previous version's attachment didn't come through
> properly, so here's an inline HTML version.
> Static Methods in Interfaces
> This is version 1.0.
> The latest version can be found at http://tinyurl.com/static-methods-in-interfaces
> Reinier Zwitserloot
> Roel Spilker
> FEATURE SUMMARY:
> Static methods are now allowed in interfaces. The static method is
> defined with a method body in the interface and it exists in the
> namespace of the interface; it does not imply that implementing
> classes must implement the method. This feature is especially useful
> for utility methods that belong with a given interface. For example,
> many methods in java.util.Collections are specific for a particular
> interface, such as sort (java.util.List) and unmodifiableMap
> The usual solution to this problem right now is to offer a separate
> utility class (a class that is not instantiable and contains only
> static methods) that contain the utility methods, along with a
> reference in the javadoc of the interface to this utility class. For
> example, java.util.Collections is the utility class that goes with
> Map, List, Set and other Java Collections API interfaces. The use case
> of default / common implementations is currently handled by having an
> implementing class with a constructor. For example, a new class called
> java.io.ExtensionFileFilter could be made that takes a String and
> implements FileFilter. The sugar employed by this proposal is itself
> also an alternative: Creating a member type class that contains the
> static methods (With just a backwards and migration compatible API
> addition, you could make List.Utils.of(items) work in java 1.6
> notation (The Utils class is an inner member type to the interface,
> which is legal, and as it is a class, may contain static methods.
Adding extension methods would be alternative to address the same problem.
> LIBRARY SUPPORT:
> No library support is needed. However, it would be advisable to update
> various interfaces in the core java APIs with useful static utility
> methods. Some examples:
> java.util.List/Map/Set: All methods in java.util.Collections should
> also be made available on the appropriate java collections API
> java.io.Closeable: should contain a utility method
> 'closeAndIgnoreException' (arguably better suited on InputStream
> java.util.List/Set: Should contain an 'of' method that makes
> unmodifiable lists and sets via varargs.
> java.io.FileFilter: Should contain an 'ofExtension(String)' method
> that creates a FileFilter for the provided extension.
> REFLECTIVE APIS:
> Currently, synthetic members are not treated specially by the
> reflection API. Therefore, this proposal does not require any
> reflective API changes. However, if transparency of the static method
> in interfaces proposal is required for the reflection API, the
> following 4 changes need to be made:
> There are 3 methods in java.lang.Class which need minor changes:
> getMethod(), getDeclaredMethods(), and getMethods(). These method
> finders will need to presume all static methods in a member type
> called $Methods are considered part of the type itself, and thus need
> to be returned as well, if the class object represents an interface.
> Because getDeclaredMethods() doesn't return methods in supertypes, and
> getMethod()/getMethods() only return accessible members of supertypes,
> none of these methods need to look in $Methods inner types of
> supertypes. These methods just need to look in the actual interface
> represented by the class object for a $Methods.
> There is one method in java.lang.Method that needs a minor change: the
> getDeclaringClass() method needs to return the Class object
> representing the interface, and not the $Methodssynthetic class, when
> invoked on a static method of an interface.
Similar questions would have to be answered for various methods in the
> OTHER CHANGES:
> No changes required.
Javadoc output comes to mind.
> No migration is needed. However, any java projects that currently
> employ utility classes (defined as having a private constructor that
> is not called anywhere in scope) which either return interface types,
> or take as first parameter an interface type, or both, where all
> previously mentioned interfaces are in the same package, are likely
> candidates for moving or copying to the relevant interface. Thus, IDEs
> can offer refactor advice to perform this task automatically and to
> find likely candidates. Such a refactor tool would for example
> identify all methods injava.util.Collections.
> BREAKING CHANGES:
> Existing source that already uses an inner type named $Methods in an
> interface will change semantics when this proposal is implemented,
> primarily when queried via reflection. Between the vanishingly small
> odds of both a $Methods already existing and its methods being queried
> by the reflection API, and the general rule that $ should only be used
> in type names by compilers, the potential breaking change is hardly
> worth mentioning.
> EXISTING PROGRAMS:
> Existing programs are not affected by this change, other than as
> described above in the 'breaking changes' section.
> EXISTING BUGS:
Searching for "site:bugs.sun.com static method interface" in a popular
search engine yields many relevant bugs.
More information about the coin-dev