Java 反射调用静态方法

五迷三道 提交于 2020-01-19 06:50:43

专栏原创出处:github-源笔记文件 github-源码 ,欢迎 Star,转载请附上原文出处链接和本声明。

Java 核心知识专栏系列笔记,系统性学习可访问个人复盘笔记-技术博客 Java 核心知识

一、使用 java.lang.reflect 包的 Method#invoke 调用

关键代码:Object invoke = method.invoke(null, Object... args),从底层方法被调用的对象设置为 null 即可。

public class ReflectExample {

    public static String stringStaticMethod(String s) {
        return s + "|" + s;
    }

    public static void main(String[] args) throws Throwable {
        Method method = ReflectExample.class.
            getDeclaredMethod("stringStaticMethod", String.class);
        
        Object invoke = method.invoke(null, "invoke"); // obj 传 null
        System.out.println(invoke); // invoke|invoke
    }
}

java.lang.reflect.Method 类对应 invoke 方法说明:

在具有指定参数的方法对象上调用此方法对象表示的基础方法。 个别参数自动解包以匹配原始形式参数,原始参考参数和参考参数都需要进行方法调用转换。

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

  • 如果底层方法所需的形式参数的数量为 0,则提供的 args 数组的长度为 0 或为空。

  • 如果底层方法是一个实例方法,它将使用动态方法查找来调用,如“Java 语言规范”第二版,第 15.12.4.4 节所述; 特别是将会发生基于目标对象的运行时类型的覆盖。

  • 如果底层方法是静态的,则如果尚未初始化该方法,那么声明该方法的类将被初始化。

  • 如果方法正常完成,则返回的值将返回给调用者; 如果值具有原始类型,则首先将其适当地包装在对象中。 但是,如果该值具有基本类型的数组的类型,则该数组的元素不会包含在对象中; 换句话说,返回一个原始类型的数组。 如果底层方法返回类型为 void,则调用返回 null。

二、使用 java.lang.invoke 包的 MethodHandle 调用

JDK 7 为间接调用方法提供了 MethodHandle 类,即方法句柄。可以将其看作是反射的另一种方式。主要是为了虚拟机直接提供的动态语言支持。

public class InvokeExample {

    public static String stringStaticMethod(String s) {
        return s + "|" + s;
    }
    
    public static void main(String[] args) {
        // 获取静态方法类型:返回值与参数均为 String
        MethodType methodType = MethodType.methodType(String.class, String.class);
        
        // 获取静态方法的句柄
        MethodHandle method =  MethodHandles.lookup()
        .findStatic(InvokeExample.class, "stringStaticMethod", methodType);
        
        // 调用方法
        Object r = method.invoke("invoke"); // invoke|invoke
    }
}

对 java.lang.invoke 包更深入的分析了解参考推荐专栏相关文章。

推荐

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!