PROPOSAL: Static Methods in Interfaces (original) (raw)
Joseph D. Darcy Joe.Darcy at Sun.COM
Tue Mar 17 15:27:19 PDT 2009
- Previous message: PROPOSAL: Static Methods in Interfaces
- Next message: Proposal: Automatic Resource Management
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message: PROPOSAL: Static Methods in Interfaces
- Next message: Proposal: Automatic Resource Management
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]