PROPOSAL: Static Methods in Interfaces

Joseph D. Darcy Joe.Darcy at Sun.COM
Tue Mar 17 15:27:19 PDT 2009


Hello.

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
>
> VERSION
>
> This is version 1.0.
> The latest version can be found at http://tinyurl.com/static-methods-in-interfaces
> AUTHOR(S):
>
> Reinier Zwitserloot
> Roel Spilker
> OVERVIEW
>
> 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  
> (java.util.Map).
>   

[snip]

> ALTERNATIVES:
>
> 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.


[snip]

>
> 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  
> interface.
> java.io.Closeable: should contain a utility method  
> 'closeAndIgnoreException' (arguably better suited on InputStream  
> instead).
> 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 
javax.lang.model.* API.

> OTHER CHANGES:
>
> No changes required.
>   

Javadoc output comes to mind.

> MIGRATION:
>
> 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.
>
> COMPATIBILITY
>
> 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.
>
> REFERENCES
>
> EXISTING BUGS:
>
> None.
>   

Searching for "site:bugs.sun.com static method interface" in a popular 
search engine yields many relevant bugs.

-Joe



More information about the coin-dev mailing list