使用反射调用java / groovy对象的静态方法

时间:2012-05-03 19:25:30

标签: java reflection groovy

我正在研究一个groovy单元测试类,它包含一组规则,用于判断文件内容是否格式正确。 (没有使用适当的规则引擎,它只是利用Groovy的断言功能以一种模糊地类似于规则引擎的方式进行验证。)我在想我可以创建一个名为FireAllRules的方法,如下所示: / p>

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一起出现的无趣的方法。有没有办法在运行时使用反射来迭代这些静态方法?

3 个答案:

答案 0 :(得分:5)

假设:

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 )

答案 1 :(得分:3)

静态方法包含在getMethods()返回的方法中。您的问题可能是method.name.indexOf("rule" == 0)。这应该是method.name.indexOf("rule") == 0,或者更好method.name.startsWith("rule")

另外,您的规则方法是公开的吗?如果没有,您可以使用getDeclaredMethods()。要调用它们,您必须先调用setAccessible()

答案 2 :(得分: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"); }
}