私は結局アレックスの提案に行きました。BeanUtils は Bean に大いに役立ちますが、Bean だけで作業したくありません。FEST は非常に優れているようで、さらに調査するためにブックマークしましたが、BeanUtils と同様に、ここで難しい問題であると私が考えるものを解決するようには見えません。つまり、メソッド名と引数のリストを指定して、引数に最も「適合する」メソッドを選択します。メソッドが float を取り、double を持っている場合、署名が正確に一致しないためにそのメソッドを拒否しないように十分にスマートにする必要があります。
明らかに、JVM 上に構築されたスクリプト言語はこの問題を解決しますが、言語固有の最適化により、必要以上に複雑な方法になります。したがって、これは小規模で実験的な機能であるため、Java 1.6 のスクリプト エンジン サポート (特に JavaScript) を使用する迅速な解決策を選択しました。基本的な考え方は次のとおりです。
private ScriptEngine engine = ... initialize with JavaScript engine ...
private Object invoke(Object object, String methodName, Object[] args)
throws RhsFunctionException
{
// build up "o.method(arg0, arg1, arg2, ...)"
StringBuilder exp = new StringBuilder("o." + methodName);
engine.put("o", object);
buildArgs(arguments, exp);
try {
return engine.eval(exp.toString());
}
catch (ScriptException e) {
throw new RhsFunctionException(e.getMessage(), e);
}
}
private void buildArgs(Object[] args, StringBuilder exp)
{
// Use bindings to avoid having to escape arguments
exp.append('(');
int i = 0;
for(Symbol arg : args) {
String argName = "arg" + i;
engine.put(argName, arg);
if(i != 0) {
exp.append(',');
}
exp.append(argName);
++i;
}
exp.append(')');
}
明らかにそれにはもう少し多くのことがありますが、これが基本的な考え方です。文字列を構築して評価するのはあまり好きではありませんが、Alex が提案したバインディングを使用することで、エスケープに関する落とし穴のほとんどを回避できます。さらに、必要に応じて「実際の」実装と交換できる、クリーンでシンプルなインターフェイスがあります。
フィードバックや代替ソリューションは大歓迎です。