関数名を文字列としてハッシュテーブルに保存している場合。
保存された文字列を介して関数にアクセスする方法はありますか?
編集CLDC1.1/MIDP2.0で作業しているプラットフォームがReflectionをサポートしていないのではないかと思います。
可能な回避策はありますか?
else-ifの大きな長いリストを使用するだけです。
[...]
} else if ("foo".equals(function)) {
target. foo();
} else if ("bar".equals(function)) {
target. bar();
[...]
(私は通常、ソースで垂直方向の配置を試みるのは好きではありませんが、このような場合はそれだけの価値があると思います。)
マップにファンクターを格納することもできます。buは、多くのMIDPアプリケーションでオブジェクトサイズを大きくしすぎる可能性があります。
Class.forName()とnewInstance()はMIDP 1.1にあるはずであり、役に立つかもしれません。完全なリフレクションがないため、すべての関数呼び出しをラップして呼び出すクラスを作成できます。これは、すべての関数呼び出しを事前に知っていることを前提としています。
静的呼び出しを行っていない限り、すべてのオブジェクトへの参照が必要になります。ちょっと面倒ですが、仕事は終わります。
public Object invoke(String name, Object[] args) {
Object f = functionMap.get(name);
if("f1".equals(name)) {
return ((SomeInterface1)f).someFunction1((SomeArg0) args[0]), ...);
} else if ("f2".equals(name)) {
return ((SomeInterface2)f).someFunction2((SomeArg0) args[0]), ...);
}...{
} else if ("fN".equals(name)) {
return ((SomeInterfaceN)f).someFunctionN((SomeArg0) args[0]), ...);
}
}
関数名を指定すると、リフレクションを使用してメソッドにアクセスできます。関数の名前に加えて、そのクラスを知っている必要があります(または、noargコンストラクターがある場合、またはコンストラクターに渡すパラメーターがわかっている場合は、リフレクションを介して作成します)インスタンス(メソッドが静的でない場合)と渡すために必要なパラメータを知っている必要があります。
もう1つのオプションは、メソッドクラスを関数へのポインタとして使用することです。クラスを知り、パラメータ要件を知るという利点があります。シリアル化できないという欠点があります。
編集:名前を文字列として持つだけでは、リフレクションなしでJavaのメソッドにアクセスする方法はありません。メソッドへの代替ポインターが必要な場合は、既知のインターフェースを実装する必要なメソッドを呼び出し、それをマップに渡す匿名の内部クラスを使用できます。これはマップのキーとしては適切ではありませんが、マップの値としては機能します。
javameでリフレクションを試したことはありませんが、javaseではリフレクションを使用してメソッドを動的に呼び出すことができます。
次のスニペットは、http: //java.sun.com/developer/technicalArticles/ALT/Reflection/から取得されます。
import java.lang.reflect.*;
public class method2 {public int add(int a、int b){return a + b; }
public static void main(String args[])
{
try {
Class cls = Class.forName("method2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod(
"add", partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj
= meth.invoke(methobj, arglist);
Integer retval = (Integer)retobj;
System.out.println(retval.intValue());
}
catch (Throwable e) {
System.err.println(e);
}
}
}
編集:if..then..elseを使用するのではなく、実際に番号を返し、スイッチを使用することをお勧めします。IMOの方が読みやすいからです。
しかし、それにもかかわらず、JavaMEの制限を考えると、おそらくそれが唯一の選択肢です。
J2MEで実行されるインタープリターであるHeclでも同様の問題を扱っています。処理する文字列の数によって異なりますが、機能する1つの方法は、ハッシュを使用して整数を検索し、if / thenステートメントの大きなリストではなく、switchステートメントでそれを使用することです。ちなみに、Heclソースコードを使用することは大歓迎です。リベラルなApacheライセンスの下で利用できます。