web-dev-qa-db-ja.com

変数名を使用してJavaメソッドを呼び出す方法は?

たとえば、Method1(void)、Method2(void)...

変数を持つものを選択する方法はありますか?

 String MyVar=2;
 MethodMyVar();
26
Adam Outler

リフレクションを使用する:

Method method = WhateverYourClassIs.class.getDeclaredMethod("Method" + MyVar);
method.invoke();
35
Nathan Hughes

反射を通してのみ。 _Java.lang.reflect_パッケージを参照してください。

あなたは次のようなことを試すことができます:

_Method m = obj.getClass().getMethod("methodName" + MyVar);
m.invoke(obj);
_

メソッドにパラメーターがあり、あらゆる種類の例外処理が欠落している場合は、コードが異なる場合があります。

しかし、これが本当に必要かどうか自分に尋ねてください。これを回避するために、設計について何か変更できますか?リフレクションコードは理解が難しく、単にobj.someMethod()を呼び出すよりも時間がかかります。

幸運を。ハッピーコーディング。

9
Todd

Strategyデザインパターンと、必要な文字列から対応する具象戦略オブジェクトへのマッピングを使用できます。これは安全で効率的な手段です。

だから、HashMap<String,SomeInterfaceYouWantToInvokeSuchAsRunnableWithPseudoClosures> 調べる。

たとえば、次のようなものがあります。

final static YourType reciever = this;
HashMap<String,Runnable> m = new HashMap<String,Runnable> {{
    put("a", new Runnable() {
       @Override public void run () {
         reciever.a();
       }
    });
    ....
}};
// but check for range validity, etc.
m.get("a").run()

リフレクションを使用するか、問題を「反転」して、ポリモーフィズムを使用することもできます

6
user166390

静的メソッドの最初の引数がnullである場合を除き、受け入れられた回答がmethod.invoke()でどのように機能するかはわかりません(ダミー値を入力しても機能します)。 Java™チュートリアル によると:

最初の引数は、この特定のメソッドが呼び出されるオブジェクトインスタンスです。 (メソッドが静的の場合、最初の引数はnullでなければなりません。)

以下は、完全な例(Main.Java)の両方の静的(クラス別)VS非静的(インスタンス別)、およびメソッドの引数付きの追加例import必要なクラス、catch例外、およびスーパークラスメソッドの例。

import Java.lang.reflect.Method;
import Java.lang.reflect.InvocationTargetException;

class Love {
   protected void Method4() {
        System.out.println("calls super protected method by instance");
    }

   public void Method5() {
        System.out.println("calls super public method by instance");
    }
}

class Main extends Love {

    static void Method2(int y) {
        System.out.println("by class: " + y);
    }

    void Method3(String y) {
        System.out.println(y);
    }

    public static void main(String[] args) {

        String MyVar = "2";
        String MyAnotherVar = "3";
        String MySuperVar = "4";
        String MySuperPublicMethodVar = "5";
        Main m = new Main();

       try {
            Method method = Main.class.getDeclaredMethod("Method" + MyVar, int.class); //by class
            Method anotherMethod = m.getClass().getDeclaredMethod("Method" + MyAnotherVar, String.class); //by instance
            Method superMethod = m.getClass().getSuperclass().getDeclaredMethod("Method" + MySuperVar); //super method by instance, can be protected
            Method superPublicMethod = m.getClass().getMethod("Method" + MySuperPublicMethodVar); //getMethod() require method defined with public, so even though sublcass calls super protected method will not works
            try {
                method.invoke(null, 10000);//by class
                anotherMethod.invoke(m, "by instance"); //by instance
                superMethod.invoke(m); //super method by instance
                superPublicMethod.invoke(m); //super's public method by instance
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }

       } catch (NoSuchMethodException e) {
           throw new RuntimeException(e);
       } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
       }
    }
}

出力:

$ javac Main.Java
$ Java Main 
by class: 10000
by instance
calls super protected method by instance
calls super public method by instance
$ 
0
林果皞