クロージャがない場合に、Javaの(プリミティブ)コールバック機能を提供する汎用のCallbackオブジェクトがあります。Callbackオブジェクトにはメソッドが含まれており、メソッド内の同等のメソッドに委任するだけの2つのアクセサーメソッドを介して、メソッドのパラメーターと戻り値のタイプを返します。
提供されたコールバックが有効なメソッドを指していることを検証しようとしています。Numberと互換性のある戻り型の割り当てと、Doubleと互換性のある割り当てであるすべてのパラメーターが必要です。私の検証方法は次のようになります。
static public void checkFunctionSpec(Callback cbk) {
Class[] prms=cbk.getParmTypes();
Class ret =cbk.getReturnType();
if(!Number.class.isAssignableFrom(ret)) {
throw new IllegalArgumentException(
"A function callback must return a Number type " +
"(any Number object or numeric primitive) - function '" +
cbk + "' is not permitted");
}
for(Class prm: prms) {
if(!Double.class.isAssignableFrom(prm)) {
throw new IllegalArgumentException(
"A function callback must take parameters of " +
"assignment compatible with double " +
"(a Double or Float object or a double or float primitive) " +
"- function '" + cbk + "' is not permitted");
}
}
}
私が遭遇する問題は、たとえばMath.abs()でこれを試してみると、次のように戻り型の例外がスローされることです。
java.lang.IllegalArgumentException:
A function callback must return a Number type (any Number object or numeric primitive)
- function 'public static double java.lang.Math.abs(double)' is not permitted
これは、プリミティブが(a)ラッパークラスを使用して反映され、(b)Double.TYPEがClass <Double>型であると宣言されているため、プリミティブが単純に機能することを期待していたため、私には驚きました。
チェックを変更せずにこれを達成する方法を誰かが知っていますか?
if(!Number.class.isAssignableFrom(ret)
&& ret!=Double.TYPE
&& ret!=Float.TYPE
&& ret!=...) {
明確化
double abs(double)
Method.invoke()を使用してメソッドを呼び出すときは、Object [] {Double}を渡して、Doubleを返します。ただし、Double.TYPEをDoubleに割り当てることができないため、検証が失敗しているように見えます。これらすべてのコールバックで、invoke()によって数値として返されるある種の数値を返す必要があるため、提供されたメソッドが数値または数値プリミティブのいずれかを返すことを検証しようとしています。
parmsの検証も同様です。
つまり、リフレクションを使用する場合、parmタイプとreturnタイプのDoubleとdoubleは同じであり、そのように簡単に検証したいと思います。
編集:さらに明確にするために:invoke()が呼び出されたときに、メソッドがNumber型のオブジェクトを返すことを検証したいと思います(そこからobj.doubleValue()を呼び出して必要なdoubleを取得できます)。