PROPOSAL: Improved Support for Optional Object Behaviors at Runtime

Joe Darcy Joe.Darcy at Sun.COM
Tue May 12 18:00:19 PDT 2009


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