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

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

相关推荐
追随者永远是胜利者3 分钟前
(LeetCode-Hot100)53. 最大子数组和
java·算法·leetcode·职场和发展·go
百锦再27 分钟前
Java之Volatile 关键字全方位解析:从底层原理到最佳实践
java·开发语言·spring boot·struts·kafka·tomcat·maven
张万森爱喝可乐39 分钟前
Java高并发实战
java
daad7771 小时前
rcu 内核线程
java·开发语言
百锦再1 小时前
Java JUC并发编程全面解析:从原理到实战
java·开发语言·spring boot·struts·kafka·tomcat·maven
前路不黑暗@3 小时前
Java项目:Java脚手架项目的登录认证服务(十三)
java·spring boot·笔记·学习·spring·spring cloud·maven
番茄去哪了3 小时前
苍穹外卖day05----店铺营业状态设置
java·数据库·ide·redis·git·maven·mybatis
QQ 31316378904 小时前
文华指标公式大全通道划线指标
java
前路不黑暗@4 小时前
Java项目:Java脚手架项目的 C 端用户服务(十五)
java·开发语言·spring boot·学习·spring cloud·maven·mybatis