我有同样的需求,因为我们有代码需要运行在Java 1.2的所有版本的Java上,但是如果代码可用,一些代码需要利用更新的API。
在使用反射来获取方法对象并动态调用它们的各种排列之后,一般来说,我已经将包装风格的方法定为最佳方法(尽管在某些情况下,仅仅将反射方法存储为静态方法并调用它更好,这取决于具体情况)。
下面是一个示例“系统实用工具”类,它在运行早期版本时为Java 5公开某些更新的API,在早期JVM中,Java 6使用相同的原则。这个例子使用了一个单例,但是如果底层API需要的话,可以很容易地实例化多个对象。
有两类:
西索尔
雪松J5
后者是运行时JVM是Java 5或更高版本时使用的。否则,在契约中兼容的回退方法将从SysUtil的默认实现中使用,该实现仅使用Java 4或更早的API。每个类都是用特定版本的编译器编译的,因此Java 4类中没有意外使用Java 5 + API:
SyStul(用Java 4编译器编译)
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() {
return 1;
}
/** Package protected to allow subclass SysUtil_J5 to override it. */
long milliTime() {
return System.currentTimeMillis();
}
/** Package protected to allow subclass SysUtil_J5 to override it. */
long nanoTime() {
return (System.currentTimeMillis()*1000000L);
}
// *****************************************************************************
// STATIC PROPERTIES
// *****************************************************************************
static private final SysUtil INSTANCE;
static {
SysUtil instance=null;
try { instance=(SysUtil)Class.forName("SysUtil_J5").newInstance(); } // can't use new SysUtil_J5() - compiler reports "class file has wrong version 49.0, should be 47.0"
catch(Throwable thr) { instance=new SysUtil(); }
INSTANCE=instance;
}
// *****************************************************************************
// STATIC METHODS
// *****************************************************************************
/**
* Returns the number of processors available to the Java virtual machine.
*
* This value may change during a particular invocation of the virtual machine. Applications that are sensitive to the
* number of available processors should therefore occasionally poll this property and adjust their resource usage
* appropriately.
*/
static public int getAvailableProcessors() {
return INSTANCE.availableProcessors();
}
/**
* Returns the current time in milliseconds.
*
* Note that while the unit of time of the return value is a millisecond, the granularity of the value depends on the
* underlying operating system and may be larger. For example, many operating systems measure time in units of tens of
* milliseconds.
*
* See the description of the class Date for a discussion of slight discrepancies that may arise between "computer time"
* and coordinated universal time (UTC).
*
* @return The difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
*/
static public long getMilliTime() {
return INSTANCE.milliTime();
}
/**
* Returns the current value of the most precise available system timer, in nanoseconds.
*
* This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock
* time. The value returned represents nanoseconds since some fixed but arbitrary time (perhaps in the future, so values
* may be negative). This method provides nanosecond precision, but not necessarily nanosecond accuracy. No guarantees
* are made about how frequently values change. Differences in successive calls that span greater than approximately 292
* years (263 nanoseconds) will not accurately compute elapsed time due to numerical overflow.
*
* For example, to measure how long some code takes to execute:
*
* long startTime = SysUtil.getNanoTime();
* // ... the code being measured ...
* long estimatedTime = SysUtil.getNanoTime() - startTime;
*
*
* @return The current value of the system timer, in nanoseconds.
*/
static public long getNanoTime() {
return INSTANCE.nanoTime();
}
} // END PUBLIC CLASS
SysTurijJ5(用Java 5编译器编译)
import java.util.*;
class SysUtil_J5
extends SysUtil
{
private final Runtime runtime;
SysUtil_J5() {
super();
runtime=Runtime.getRuntime();
}
// *****************************************************************************
// INSTANCE METHODS
// *****************************************************************************
int availableProcessors() {
return runtime.availableProcessors();
}
long milliTime() {
return System.currentTimeMillis();
}
long nanoTime() {
return System.nanoTime();
}
} // END PUBLIC CLASS