私は長い間、JSE で 1.1 以降のすべての JVM をサポートする必要があり、この種のラッピング手法を使用して、オプションの API (つまり、アプリケーションの動作を改善するが必須ではない API) を互換的にサポートしてきました。
私が使用する 2 つの手法は、参照した記事に (不十分に?) 記載されているようです。それについてさらにコメントするのではなく、私がこれをどのように行ったかの実際の例を提供します.
最も簡単 - 静的ラッパー メソッド
必要: API が利用可能であればそれを呼び出すか、そうでなければ何もしないこと。これは、任意の JVM バージョンに対してコンパイルできます。
Method
まず、次のように、反映されたメソッドを持つ静的を設定します。
static private final java.lang.reflect.Method SET_ACCELERATION_PRIORITY;
static {
java.lang.reflect.Method mth=null;
try { mth=java.awt.Image.class.getMethod("setAccelerationPriority",new Class[]{Float.TYPE}); } catch(Throwable thr) { mth=null; }
SET_ACCELERATION_PRIORITY=mth;
}
直接呼び出しを使用する代わりに、反映されたメソッドをラップします。
static public void setImageAcceleration(Image img, int accpty) {
if(accpty>0 && SET_ACCELERATION_PRIORITY!=null) {
try { SET_ACCELERATION_PRIORITY.invoke(img,new Object[]{new Float(accpty)}); }
catch(Throwable thr) { throw new RuntimeException(thr); } // exception will never happen, but don't swallow - that's bad practice
}
}
Harder - 静的ラッパー クラス
必要: API が使用可能な場合はその API を呼び出すか、それ以外の場合は、同等ではあるが機能が低下した古い API を呼び出します。これは、新しい JVM バージョンに対してコンパイルする必要があります。
最初に静的ラッパー クラスを設定します。これは静的なシングルトン ラッパーである場合もあれば、すべてのインスタンス作成をラップする必要がある場合もあります。次の例では、静的シングルトンを使用しています。
package xxx;
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();
}
/** 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 milliTick() {
return System.currentTimeMillis();
}
/** Package protected to allow subclass SysUtil_J5 to override it. */
long nanoTick() {
return (System.currentTimeMillis()*1000000L);
}
// *****************************************************************************
// STATIC PROPERTIES
// *****************************************************************************
static private final SysUtil INSTANCE;
static {
SysUtil instance=null;
try { instance=(SysUtil)Class.forName("xxx.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 value of the most precise available system timer, in milliseconds.
* <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 milliseconds since some fixed but arbitrary time (perhaps in the future, so
* values may be negative). This method provides millisecond precision, but not necessarily millisecond accuracy. No
* guarantees are made about how frequently values change. Differences in successive calls that span greater than
* approximately 292,000 years 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.getNanoTick();
* // ... the code being measured ...
* long estimatedTime = SysUtil.getNanoTick() - startTime;
* </pre>
* <p>
* @return The current value of the system timer, in milliseconds.
*/
static public long getMilliTick() {
return INSTANCE.milliTick();
}
/**
* 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 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.getNanoTick();
* // ... the code being measured ...
* long estimatedTime = SysUtil.getNanoTick() - startTime;
* </pre>
* <p>
* @return The current value of the system timer, in nanoseconds.
*/
static public long getNanoTick() {
return INSTANCE.nanoTick();
}
} // END PUBLIC CLASS
利用可能になったときに新しい機能を提供するサブクラスを作成します。
package xxx;
import java.util.*;
class SysUtil_J5
extends SysUtil
{
private final Runtime runtime;
SysUtil_J5() {
super();
runtime=Runtime.getRuntime();
}
int availableProcessors() {
return runtime.availableProcessors();
}
long milliTick() {
return (System.nanoTime()/1000000);
}
long nanoTick() {
return System.nanoTime();
}
} // END PUBLIC CLASS