探究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. 结论

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

相关推荐
Chase_______17 小时前
【Java杂项】final 关键字详解:变量、方法、类限制与引用可变性
java·开发语言·python
凤山老林17 小时前
DDD(领域驱动设计)在复杂业务系统中的落地指南
java·开发语言·数据库·ddd·领域驱动
JEECG低代码平台18 小时前
JimuChatBI — 首款免费开源的 Java 智能问数ChatBI平台,零成本接入,AI对话式智能分析
java·人工智能·开源·aigc·人工智能低代码
星梦清河18 小时前
Java—异步编程
java·开发语言
GIS数据转换器18 小时前
智慧能源管理平台
java·大数据·运维·人工智能·无人机
garmin Chen18 小时前
LeetcodeHot100打卡(14、合并空间,15、轮转数组,16、除了自身以外数组乘积,17.缺失的第一个整数)
java·笔记·学习·算法
接着奏乐接着舞19 小时前
dto 转entity方法
java·开发语言
我命由我1234519 小时前
Android 开发问题:项目同时引入了两个包含相同类文件的库(AndroidX 库、旧版本支持库),导致了重复类错误
android·java·java-ee·android studio·android-studio·androidx·android runtime
梓色系19 小时前
Spring AI 实战:从零搭建 MCP 客户端与服务端,让大模型拥有“手脚“
java·人工智能·spring
秦时星星19 小时前
Spring AI + FastMCP 跨语言集成踩坑实录
java·人工智能·spring