3

I'm working on a groovy unit-testing class that contains a collection of rules for whether or not the contents of a file are correctly formatted. (Not using a proper rules engine, it just takes advantage of Groovy's assertion capabilities to do validation in a way that vaguely resembles what a rules engine would do.) I was thinking that I could create a method called FireAllRules that looks like this:

public static void FireAllRules(File file)
{
    for(def method in Class.getMethods)
    {
        if(method.name.indexOf("rule" == 0) method.invoke(file);
    }
}

ループで取得するメソッドはすべて静的であり、デバッグ プロセス中に Class.getMethods() 列挙にルール メソッドが含まれていないことに気付きました。理想的には、java.Object に付随する何十もの興味のないメソッドをソートするのではなく、私が個人的にクラスに書き込んだメソッドだけをループしたいと考えています。実行時にこれらの静的メソッドを反復するためにリフレクションを使用する方法はありますか?

4

3 に答える 3

6

与えられた:

class Test {
  public static testThis() {
    println "Called testThis"
  }

  public static woo() {
    println "Called woo"
  }

  public static testOther() {
    println "Called testOther"
  }
}

できるよ:

Test.metaClass.methods.grep { it.static && it.name.startsWith( 'test' ) }.each {
  it.invoke( Test )
}

印刷する:

Called testOther
Called testThis

クラスの静的テスト メソッドを実行するためのより一般的なメソッドは次のようになります。

def invokeClass( clazz ) {
  clazz.metaClass.methods.grep { it.static && it.name.startsWith( 'test' ) }.each {
    it.invoke( clazz )
  }
}

invokeClass( Test )
于 2012-05-03T19:44:13.073 に答える
3

によって返されるメソッドには、静的メソッドが含まれgetMethods()ます。あなたの問題はmethod.name.indexOf("rule" == 0). method.name.indexOf("rule") == 0これは、またはさらに良いはずmethod.name.startsWith("rule")です。

また、あなたのルールメソッドは公開されていますか? そうでない場合は、使用できますgetDeclaredMethods()。それらを呼び出すには、setAccessible()最初に呼び出す必要があります。

于 2012-05-03T19:40:49.970 に答える
2

Javaバージョンは次のようになります(わかりやすくするために、インポートと例外を削除しました)。

public class FindAndRunStaticMethods {
    public static void main(String[] args) {
        fireAllRules();
    }

    public static void fireAllRules() {
        for(Method method : StaticMethodClass.class.getDeclaredMethods()) {
            findAndRunRules(method);
        }
    }

    private static void findAndRunRules(Method method) {
        if (!Modifier.isStatic(method.getModifiers())) return;
        if (!method.getName().startsWith("rule")) return;
        if (!method.getReturnType().equals(Void.TYPE)) return;

        Class[] parameterTypes = method.getParameterTypes();

        if (parameterTypes.length != 1) return;
        if (!parameterTypes[0].equals(File.class)) return;

        method.invoke(null, new File("dummy"));
    }
}

サンプルテストクラスは次のようになります

public class StaticMethodClass {
    public static void ruleHere(File x) { System.out.println("should print"); }
    public static void ruleRun(File x) { System.out.println("should print"); }  
    public void ruleNotSelected() { System.out.println("not run"); }
}
于 2012-05-04T00:47:49.653 に答える