使用反射调用静态方法


198

我想调用main静态的方法。我得到了类型的对象Class,但是我无法创建该类的实例,也无法调用该static方法main

Answers:


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参数。它可以为空。

当你会发生什么

类别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容易得多,因为getMethod(或getDeclaredMethod)要求您详细确定参数类型。这仅取决于微效率是否重要-Java迭代非常快,因此,除非您在某个内部循环中调用该方法数百万次,否则迭代将足够快
Tony Eastwood 2013年

2
同样,在更实际的情况下,即使您打算多次使用反射来调用它,您也可能只会找到一次该方法。因此,发现它时的额外开销并不重要。
RenniePet 2015年

4
但是使用重载方法会很糟糕。
Ulysse Mizrahi

1
@UlysseMizrahi都取决于您匹配的内容,但是是的,如果您正在编写库代码,仅依靠名称可能很危险。我通常检查特定的批注或特定的方法签名,例如“采用String并返回类实例的静态方法”,然后断言只有一个这样的方法。
cobbzilla

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

在上面的示例中,“ add”是一个静态方法,它使用两个整数作为参数。

以下代码段用于通过输入1和2调用“ add”方法。

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

参考链接

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.