I have had this same need, since we have code that needs to run on all versions of Java from Java 1.2, but some code needs to take advantage of newer API's if they are available.
After various permutations using reflection to obtain Method objects and invoking them dynamically, I have settled on a wrapper style approach as best, in general (although under some circumstances, just storing the reflected Method as a static and invoking it is better - it depends).
Following is an example "System Utility" class which exposes certain newer API's for Java 5 when running an earlier version - the same principles hold for Java 6 in earlier JVMs. This example uses a Singleton, but could easily instantiate multiple objects if the underlying API needed that.
There are two classes:
The latter is the one used if the run-time JVM is Java 5 or later. Otherwise fallback methods which are compatible in contract are used from the default implementation in SysUtil which utilizes only Java 4 or earlier APIs. Each class is compiled with the specific version's compiler, so that there is no accidental usage of a Java 5+ API in the Java 4 class:
SysUtil (compiled with the Java 4 compiler)
import java.io.*;
import java.util.*;
/**
* Masks direct use of select system methods to allow transparent use of facilities only
* available in Java 5+ JVM.
*
* Threading Design : [ ] Single Threaded [x] Threadsafe [ ] Immutable [ ] Isolated
*/
public class SysUtil
extends Object
{
/** Package protected to allow subclass SysUtil_J5 to invoke it. */
SysUtil() {
super();
}
// *****************************************************************************
// INSTANCE METHODS - SUBCLASS OVERRIDE REQUIRED
// *****************************************************************************
/** Package protected to allow subclass SysUtil_J5 to override it. */
int availableProcessors() {
answered 2009-08-15T06:49:27.737