小さな ScriptEngine の開発の一環として、私は反射的に Java メソッドを呼び出します。スクリプト エンジンによる呼び出しにより、オブジェクトにメソッド名と引数の配列が与えられます。メソッドを呼び出すために、 Class.getMethod(name, argument types) への呼び出しで解決しようとしました。
ただし、これは、引数のクラスとメソッドによって期待されるクラスが同じ場合にのみ機能します。
Object o1 = new Object();
Object out = System.out;
//Works as System.out.println(Object) is defined
Method ms = out.getClass().getMethod("println",o1.getClass());
Object o2 = new Integer(4);
//Does not work as System.out.println(Integer) is not defined
Method mo = out.getClass().getMethod("println",o2.getClass());
正しいメソッドを取得する「簡単な」方法があるかどうか、可能であれば引数の型に最も近い方法があるかどうか、またはこれを自分で実装する必要があるかどうかを知りたいです。
最も近い適合は次のとおりです。
Object o1 = new Integer(1);
Object o2 = new String("");
getMethod(name, o1.getClass())//println(Object)
getMethod(name, o2.getClass())//println(String)
更新:
必要なものを明確にするために: スクリプト エンジンは、自由時間に書いている小さなプロジェクトなので、従わなければならない厳格な規則はありません。したがって、Javaコンパイラがコンパイル時にオブジェクトの静的型ではなく動的型のみでメソッドを選択するのと同じ方法で、エンジンから呼び出されたメソッドを選択するとうまくいくと思いました.(オートボクシングの有無にかかわらず)
これは私が最初に望んだことですClass.getMethod() が解決します。ただし、Class.getMethod() には、メソッドが宣言する引数の型とまったく同じクラスが必要です。サブクラスを使用すると、no such method Exception が発生します。これは正当な理由で発生する可能性がありますが、どの引数タイプが適合するかを事前に知らないため、メソッドが役に立たなくなります。
別の方法は、Class.getMethods() を呼び出して、返された配列を反復処理し、適切なメソッドを見つけようとすることです。ただし、最初に見つけた「良い」方法を取りたくない場合、これは複雑になるため、少なくとも処理する既存のソリューションがあることを望みました。
- 最も近い適合: arg.getClass() == サブクラスおよびメソッド m(Superclass)、m(Subclass) の場合、m(Subclass) を呼び出します
- 可変引数: System.out.printf(String ,String...)
オートボクシングのサポートもいいでしょう。
呼び出しを解決できない場合、例外がスローされる可能性があります ( ma(String,Object), ma(Object, String), args= String,String)
(ここまで作成した場合は、時間を割いて読んでくれてありがとう:- )))