リフレクションを使用して静的メソッドを呼び出す


198

main静的なメソッドを呼び出したいのですが。タイプのオブジェクトを取得Classしましたが、そのクラスのインスタンスを作成できず、staticメソッドを呼び出すこともできませんmain

回答:


290
// String.class here is the parameter type, that might not be the case with you
Method method = clazz.getMethod("methodName", String.class);
Object o = method.invoke(null, "whatever");

メソッドがのgetDeclaredMethod()代わりにプライベートに使用される場合getMethod()。そしてsetAccessible(true)、メソッドオブジェクトを呼び出します。


49

Method.invoke()のJavadocから:

基本となるメソッドが静的である場合、指定されたobj引数は無視されます。nullの可能性があります。

あなたがどうなるか

クラスklass = ...;
メソッドm = klass.getDeclaredMethod(methodName、paramtypes);
m.invoke(null、args)

13
String methodName= "...";
String[] args = {};

Method[] methods = clazz.getMethods();
for (Method m : methods) {
    if (methodName.equals(m.getName())) {
        // for static methods we can use null as instance of class
        m.invoke(null, new Object[] {args});
        break;
    }
}

11
すべてのメソッドをループする代わりに、正しい名前のgetMethodを使用しないのはなぜですか?
mjaggard 2013

11
getMethod(またはgetDeclaredMethod)では、パラメーターの型を詳細に調べる必要があるため、getMethodを使用するよりも、ループして名前でメソッドを見つける方がはるかに簡単な場合があります。それはマイクロ効率が重要かどうかに依存します-Javaの反復は非常に速いので、内部ループで何百万回もメソッドを呼び出さない限り、反復は十分に高速になります
Tony Eastwood

2
また、より現実的な状況では、リフレクションを使用して複数回呼び出す場合でも、おそらくメソッドを1回だけ見つけることになります。したがって、それを見つける際の余分なオーバーヘッドは重要ではありません。
RenniePet 2015年

4
しかし、オーバーロードされたメソッドで悪い時間を過ごすつもりです。
Ulysse Mizrahi 2016

1
@UlysseMizrahiすべては一致するものに依存しますが、ライブラリコードを記述している場合、名前だけに依存するのは危険な場合があります。私は通常、「文字列を受け取り、クラスのインスタンスを返す静的メソッド」などの特定の注釈または特定のメソッドシグネチャを確認してから、そのようなメソッドが1つだけ見つかったことを表明します。
cobbzilla 2018

0
public class Add {
    static int add(int a, int b){
        return (a+b);
    }
}

上記の例では、 'add'は2つの整数を引数として取る静的メソッドです。

次のスニペットを使用して、入力1および2で「add」メソッドを呼び出します。

Class myClass = Class.forName("Add");
Method method = myClass.getDeclaredMethod("add", int.class, int.class);
Object result = method.invoke(null, 1, 2);

参照リンク

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.