探究java反射取值与方法取值性能对比

探究java反射取值与方法取值性能对比

由于我开发框架时,经常需要对象取值。常用的取值方式有:

  • 反射取值
  • 方法调用取值

环境

同一台电脑:

jdk 21.0.2 idea 2023.3.3

1. 测试代码(常用)

1.1 反射取值

java 复制代码
    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        field();
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }

    private static List<Object> field() throws Exception {
        TestParam param = new TestParam();
        param.setA("a");
        param.setB("b");
        param.setC("c");
        List<Object> list = new ArrayList<>(8000);
        for (int i = 0; i < 5000; i++) {
            Field field = TestParam.class.getDeclaredField("a");
            field.setAccessible(true);
            list.add(field.get(param));
        }
        return list;
    }

1.2 方法调用

java 复制代码
    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        method();
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }
    
    private static List<Object> method() throws Exception {
        TestParam param = new TestParam();
        param.setA("a");
        param.setB("b");
        param.setC("c");
        List<Object> list = new ArrayList<>(8000);
        for (int i = 0; i < 5000; i++) {
            Method method = TestParam.class.getMethod("getA");
            list.add(method.invoke(param));
        }
        return list;
    }

1.3 测试结果

耗时毫秒:

反射取值 12 11 11 12 12 12
方法调用 14 15 16 16 15 15

不难看出,反射取值优胜

但是我们开发时,通常会把操作对象进行缓存,所以我们把
Method method = TestParam.class.getMethod("getA");Field field = TestParam.class.getDeclaredField("a"); 拿到for循环外,进行第二次测试。

2. 测试代码(缓存)

环境换成了笔记本

2.1 反射

java 复制代码
    public static void main(String[] args) throws Exception {
        long end = 0L, start = System.currentTimeMillis();
        for (int i = 0; i < 6; i++) {
            List<Object> list = field();
            end = System.currentTimeMillis();
            System.out.println("耗时:" + (end - start));
            start = end;
        }
    }

    private static List<Object> field() throws Exception {
        TestParam param = new TestParam();
        param.setA("a");
        param.setB("b");
        param.setC("c");
        List<Object> list = new ArrayList<>(8000);
        // 当做从缓存中拿
        Field field = TestParam.class.getDeclaredField("a");
        field.setAccessible(true); // 做了访问操作,因为是缓存,所以提前执行
        for (int i = 0; i < 5000; i++) {
            list.add(field.get(param));
        }
        return list;
    }

结果

html 复制代码
耗时:8
耗时:5
耗时:0
耗时:1
耗时:0
耗时:1

中途出现 0 不知道不知道是不是jvm优化

2.2 方法调用

java 复制代码
    public static void main(String[] args) throws Exception {
        long end = 0L, start = System.currentTimeMillis();
        for (int i = 0; i < 1; i++) {
            List<Object> list = method();
            end = System.currentTimeMillis();
            System.out.println("耗时:" + (end - start));
            start = end;
        }
    }
    
    private static List<Object> method() throws Exception {
        TestParam param = new TestParam();
        param.setA("a");
        param.setB("b");
        param.setC("c");
        List<Object> list = new ArrayList<>(8000);
        // 当做从缓存中拿
        Method method = TestParam.class.getMethod("getA");
        for (int i = 0; i < 5000; i++) {
            list.add(method.invoke(param));
        }
        return list;
    }

结果:

html 复制代码
耗时:9
耗时:8
耗时:5
耗时:4
耗时:3
耗时:4

2.3 测试结果

上面的结果是挑选了比较好的数据,不难看出,即便是缓存,也是反射优胜

3. 结论

对象取值,预先缓存反射对象,将会获得更快的取值速度。推荐使用反射取值

相关推荐
第二只羽毛7 分钟前
重载和继承的实践
java·开发语言
王嘉俊92512 分钟前
设计模式--适配器模式:优雅解决接口不兼容问题
java·设计模式·适配器模式
王嘉俊92513 分钟前
设计模式--组合模式:统一处理树形结构的优雅设计
java·设计模式·组合模式
道199320 分钟前
50 台小型无人车与50套穿戴终端 5 公里范围内通信组网方案深度研究
java·后端·struts
迎風吹頭髮26 分钟前
UNIX下C语言编程与实践35-UNIX 守护进程编写:后台执行、脱离终端、清除掩码与信号处理
java·c语言·unix
光军oi42 分钟前
全栈开发杂谈————JAVA微服务全套技术栈详解
java·开发语言·微服务
帮帮志42 分钟前
目录【系列文章目录】-(关于帮帮志,关于作者)
java·开发语言·python·链表·交互
聪明的笨猪猪43 分钟前
Java Spring “MVC ”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
Boop_wu2 小时前
[数据结构] Map和Set
java·数据结构·算法
一勺菠萝丶2 小时前
Mac 上用 Homebrew 安装 JDK 8(适配 zsh 终端)完整教程
java·python·macos