PROPOSAL: Improved Support for Optional Object Behaviors atRuntime

Schulz, Stefan schulz at e-Spirit.de
Wed May 13 00:46:16 PDT 2009


Joe wrote:
> Schulz, Stefan wrote:
> And people are free to use that pattern in their own APIs without 
> burdening all Java programmers and programs with a new method on 
> java.lang.Object.

Well, the reasons why this is not really a desired way to go are discussed in the alternative section of the proposal. A non-general API would force to use instanceof and casts before using the API, which is counterproductive with respect to its intend.

> There are plans for a separate process for API changes in JDK 7, but 
> that has not been spun-up yet:
> http://mail.openjdk.java.net/pipermail/jdk7-dev/2009-February/
> 000411.html

Thanks for the hint. :)

Alan: Are you up to re-file the proposal in case of such a process is set up? If so, let me know, whether you think the proposal would benefit of my suggestions wrt. SuperTypeToken.

Cheers, Stefan

> >> -----Original Message-----
> >> From: coin-dev-bounces at openjdk.java.net 
> >> [mailto:coin-dev-bounces at openjdk.java.net] On Behalf Of Joe Darcy
> >> Sent: Wednesday, May 13, 2009 3:00 AM
> >> To: Alan Snyder
> >> Cc: coin-dev at openjdk.java.net
> >> Subject: Re: PROPOSAL: Improved Support for Optional Object 
> >> Behaviors atRuntime
> >>
> >> Catching up on proposal email, while adding a non-final 
> >> method to Object 
> >> would be binary compatible, it would have source 
> >> compatibility effects 
> >> of unknown magnitude.  Adding methods to Object should only 
> >> be done in 
> >> extreme circumstances I don't see the problem being addressed 
> >> as being 
> >> sufficiently serious to contemplate changing Object as a solution.
> >>
> >> -Joe
> >>
> >> Alan Snyder wrote:
> >>     
> >>> Improved Support for Optional Object Behaviors at Runtime
> >>>
> >>>
> >>> AUTHOR: Alan Snyder
> >>>
> >>> OVERVIEW
> >>>
> >>> FEATURE SUMMARY:
> >>>
> >>> This proposal would add a method to class Object to allow 
> >>>       
> >> runtime access
> >>     
> >>> to optional object behaviors.
> >>>
> >>> MAJOR ADVANTAGE:
> >>>
> >>> As designs evolve and become more complex, it is useful 
> to split out
> >>> separable chunks of behavior whose support by an object 
> >>>       
> >> might be optional.
> >>     
> >>> In current Java, the universally applicable technique for 
> >>>       
> >> testing for and
> >>     
> >>> making use of optional behavior is the type cast. The type 
> >>>       
> >> cast is limited
> >>     
> >>> by its tight coupling with the type hierarchy; as a result, 
> >>>       
> >> because Java
> >>     
> >>> has single class inheritance, a class can not support an 
> >>>       
> >> optional behavior
> >>     
> >>> defined by another class that is not already in its class 
> >>>       
> >> hierarchy. In
> >>     
> >>> addition, because type casts cannot be simulated by an 
> >>>       
> >> object, it is not
> >>     
> >>> compatible with delegation. For an object implemented by 
> >>>       
> >> delegation to
> >>     
> >>> support optional behaviors using type casts, there would 
> >>>       
> >> need to be one
> >>     
> >>> delegating class for each possible combination of optional 
> >>>       
> >> behaviors.
> >>     
> >>> This proposal defines a method on class Object that can be 
> >>>       
> >> used in place
> >>     
> >>> of type casts to test for and access optional behaviors. 
> >>>       
> >> This proposal is
> >>     
> >>> not constrained by the type hierarchy of the target object, 
> >>>       
> >> because it
> >>     
> >>> permits the optional behavior to be implemented using a 
> >>>       
> >> different (but
> >>     
> >>> related) object. In addition, the determination of the 
> >>>       
> >> available behaviors
> >>     
> >>> can be made dynamically. Specifically, this proposal 
> allows a class
> >>> implemented using delegation to mimic the set of optional 
> behaviors
> >>> supported by its delegate, even if the delegate is replaceable.
> >>>
> >>> MAJOR BENEFIT:
> >>>
> >>> By adding a method to class Object, this feature can be 
> >>>       
> >> supported by any
> >>     
> >>> class, even existing Java platform classes, with no 
> >>>       
> >> additional changes to
> >>     
> >>> their class hierarchies. Because the feature is universally 
> >>>       
> >> available, the
> >>     
> >>> use of type casts for this purpose can be deprecated.
> >>>
> >>> This technique can be used to simply interfaces, or avoid 
> >>>       
> >> making them more
> >>     
> >>> complex.
> >>>
> >>> MAJOR DISADVANTAGE:
> >>>
> >>> Any change to class Object freaks people out. This is the 
> >>>       
> >> only change I
> >>     
> >>> can think of that is so obviously universal that it 
> >>>       
> >> deserves to be in
> >>     
> >>> class Object.
> >>>
> >>> ALTERNATIVES:
> >>>
> >>> One alternative is to define this method in a new interface. This
> >>> disadvantage of defining a new interface is that existing 
> >>>       
> >> classes and
> >>     
> >>> interfaces would not support the method without themselves 
> >>>       
> >> being changed.
> >>     
> >>> The other alternative is to add this method to classes and 
> >>>       
> >> interfaces on
> >>     
> >>> an as needed basis. Either alternative forces programmers 
> >>>       
> >> to use type
> >>     
> >>> casts in those cases where this method was not available. 
> Also, new
> >>> implementations of unchanged classes and interfaces would 
> >>>       
> >> not be able to
> >>     
> >>> support this feature for existing clients of those classes 
> >>>       
> >> and interfaces.
> >>     
> >>> EXAMPLE:
> >>>
> >>> Suppose a program wants to test an object "o" at runtime 
> >>>       
> >> for an optional
> >>     
> >>> behavior defined by a class or interface "T". In current 
> >>>       
> >> Java, the program
> >>     
> >>> could write:
> >>>
> >>> 	try {
> >>> 		T t = (T) o;
> >>> 		... use t ...
> >>> 	} catch (ClassCastException ex) {
> >>> 	}
> >>>
> >>> Using the proposed feature, the program would write:
> >>>
> >>> 	T t = o.getExtension(T.class);
> >>> 	if (t != null) {
> >>> 		... use t ...
> >>> 	}
> >>>
> >>> The following examples are all hypothetical, but plausible 
> >>>       
> >> to varying
> >>     
> >>> degrees. Note that many of them use instances of existing platform
> >>> classes.
> >>>
> >>> 	// Test a list to see if it is observable, and get access
> >>> 	// to the observable methods.
> >>>
> >>> 	Observable o = list.getExtension(Observable.class);
> >>>
> >>> 	// Test a file to see if supports metadata, and get access
> >>> 	// to the metadata methods.
> >>>
> >>> 	FileMetadata fm = file.getExtension(FileMetadata.class);
> >>>
> >>> 	// Test file metadata to see if Mac OS file metadata is
> >>> 	// supported. Note that the file might be on another
> >>> 	// machine, so this call might succeed even on a non-Mac system.
> >>>
> >>> 	MacOSFileMetadata mfm = 
> >>>       
> >> fm.getExtension(MacOSFileMetadata.class);
> >>     
> >>> 	// Test a file to see if it supports the new File API.
> >>> 	// Note that using this approach the new File API does
> >>> 	// not have to be an extension of the old API.
> >>>
> >>> 	java.nio.File nf = file.getExtension(java.nio.File.class);
> >>>
> >>> 	// Test a file to see if it is a directory, and get access to
> >>> 	// the directory methods.
> >>>
> >>> 	Directory dir = file.getExtension(Directory.class);
> >>>
> >>> 	// Test a file to see if it is a symlink, and get access to
> >>> 	// the symlink methods.
> >>>
> >>> 	Symlink s = file.getExtension(Symlink.class);
> >>>
> >>> 	// Test a file to see if it a directory and whether it provides
> >>> 	// read and update access to the directory contents using the
> >>> 	// List API (!).
> >>>
> >>> 	List<File> fs = (List<File>) file.getExtension(List.class);
> >>>
> >>> DETAILS
> >>>
> >>> The default definition in class Object would be:
> >>>
> >>> 	public <T> T getExtension(Class<T> c)
> >>> 	{
> >>> 		try {
> >>> 			return (T) this;
> >>> 		} catch (ClassCastException ex) {
> >>> 			return null;
> >>> 		}
> >>> 	}
> >>>
> >>> Thus, if not overridden, the method has the same effect as 
> >>>       
> >> the type cast.
> >>     
> >>> Thus it can be used in place of type casts even on 
> >>>       
> >> instances of existing
> >>     
> >>> classes.
> >>>
> >>> Once this method is in place, programmers should be 
> >>>       
> >> discouraged from using
> >>     
> >>> type casts for the purpose of testing for optional behavior.
> >>>
> >>> SPECIFICATION:
> >>>
> >>> JLS 4.3.2 would be changed to define this method.
> >>>
> >>> I'm not aware of other changes.
> >>>
> >>> MIGRATION:
> >>>
> >>> It would be advisable to convert appropriate type casts to 
> >>>       
> >> invocations of
> >>     
> >>> this method in existing code.
> >>>
> >>> Once this method is available in class Object, other Java 
> >>>       
> >> platform classes
> >>     
> >>> and APIs can be changed to take advantage of it.
> >>>
> >>> COMPATIBILITY
> >>>
> >>> BREAKING CHANGES:
> >>>
> >>> No matter what name is chosen for this method, some 
> >>>       
> >> existing program could
> >>     
> >>> fail to compile if it defines a method with the same name 
> >>>       
> >> and signature
> >>     
> >>> but (say) a different return type. Methods with class 
> parameters are
> >>> presumably uncommon.
> >>>
> >>> According to JLS 13.4.12, binary compatibility should not 
> be broken
> >>> because the method is public.
> >>>
> >>> EXISTING PROGRAMS:
> >>>
> >>> Existing classes automatically support this method to the 
> >>>       
> >> same extent that
> >>     
> >>> they current support type casts for accessing optional behavior.
> >>>
> >>>
> >>>
> >>>       
> >>
> >>
> >>     
> 
> 
> 



More information about the coin-dev mailing list