Java 1.2 からすべてのバージョンの Java で実行する必要があるコードがあるため、これと同じニーズがありましたが、新しい API が利用可能であればそれを利用する必要があるコードもあります。
リフレクションを使用してメソッド オブジェクトを取得し、それらを動的に呼び出すさまざまな順列の後、一般的に、ラッパー スタイルのアプローチが最善であることに落ち着きました (ただし、状況によっては、リフレクトされたメソッドを静的として格納し、それを呼び出す方が良い場合もありますが、場合によって異なります)。 .
以下は、特定の新しい API を公開する「システム ユーティリティ」クラスの例です。この例ではシングルトンを使用していますが、基礎となる API がそれを必要とする場合、複数のオブジェクトを簡単にインスタンス化できます。
次の 2 つのクラスがあります。
後者は、ランタイム JVM が Java 5 以降の場合に使用されるものです。それ以外の場合、コントラクトで互換性のあるフォールバック メソッドが、Java 4 以前の API のみを使用する SysUtil のデフォルトの実装から使用されます。各クラスは特定のバージョンのコンパイラでコンパイルされるため、Java 4 クラスで Java 5+ API が誤って使用されることはありません。
SysUtil (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.
* <p>
* 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.
* <p>
* 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.
* <p>
* See the description of the class Date for a discussion of slight discrepancies that may arise between "computer time"
* and coordinated universal time (UTC).
* <p>
* @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.
* <p>
* 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.
* <p>
* For example, to measure how long some code takes to execute:
* <p><pre>
* long startTime = SysUtil.getNanoTime();
* // ... the code being measured ...
* long estimatedTime = SysUtil.getNanoTime() - startTime;
* </pre>
* <p>
* @return The current value of the system timer, in nanoseconds.
*/
static public long getNanoTime() {
return INSTANCE.nanoTime();
}
} // END PUBLIC CLASS
SysUtil_J5 (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