使用反射调用静态方法

Posted

技术标签:

【中文标题】使用反射调用静态方法【英文标题】:Invoking a static method using reflection 【发布时间】:2011-01-28 21:08:02 【问题描述】:

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

【问题讨论】:

【参考方案1】:
// 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)

【讨论】:

【参考方案2】:

来自 Method.invoke() 的 Javadoc:

如果底层方法是静态的,则忽略指定的 obj 参数。它可能为空。

当你发生了什么

类类 = ...; 方法 m = klass.getDeclaredMethod(methodName, paramtypes); m.invoke(null, args)

【讨论】:

如果 m 是一个接收方法或 Callable 接口作为参数的方法【参考方案3】:
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;
    

【讨论】:

为什么不使用正确名称的 getMethod 而不是遍历所有方法? 有时循环并按名称查找方法比使用 getMethod 容易得多,因为 getMethod(或 getDeclaredMethod)要求您非常详细地计算出参数类型。这仅取决于微效率是否重要 - Java 迭代非常快,因此除非您在某个内部循环中调用该方法数百万次,否则迭代将足够快 在更真实的情况下,即使您要使用反射多次调用它,您也可能只会找到一次该方法。所以发现它时额外的开销是无关紧要的。 不过,重载方法会很糟糕。 @UlysseMizrahi 这一切都取决于您匹配的内容,但是如果您正在编写库代码,那么仅依赖名称可能很危险。我通常检查一个特定的注解,或者一个特定的方法签名,比如“接受一个字符串并返回一个类的实例的静态方法”,然后断言只找到一个这样的方法。【参考方案4】:
public class Add 
    static int add(int a, int b)
        return (a+b);
    

在上面的例子中,'add' 是一个静态方法,它接受两个整数作为参数。

下面的 sn-p 用于调用带有输入 1 和 2 的 'add' 方法。

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

参考link。

【讨论】:

以上是关于使用反射调用静态方法的主要内容,如果未能解决你的问题,请参考以下文章

使用反射调用静态方法

如何从应用程序域中所有加载的程序集中获取所有静态类并使用反射调用静态方法

面向对象之反射及内置方法

面向对象之反射及内置方法

Python系列反射

Python系列之 - 反射