Java反射 setAccessible和get/set方法效率对比

运行环境

Windows 10 专业版 19044.1766
16GB DDR4 2667MHZ
Intel i5-10500 CPU@3.10GHz
JDK 1.8 181

文章内容

对比不同Java反射操作JavaBean的耗时。
JavaBean构成

public class Note {
    private String content;
    private String colorTag;

    public Note() {
    }

    public String getContent() {
        return this.content;
    }

    public String getColorTag() {
        return this.colorTag;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setColorTag(String colorTag) {
        this.colorTag = colorTag;
    }
}

测试代码:

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
    Note note = new Note();
    long startTime = System.currentTimeMillis();
    String str = "ctx";
    int count = 1;
    int[] countArr = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};

    for (int j = 0; j < countArr.length; j++) {
        count = countArr[j];

        // 正常操作JavaBean的get/set方法
        Note normalNote = new Note();
        normalNote.setContent("1");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            normalNote = new Note();
            normalNote.setContent(str + i);
        }
        System.out.println("normal count:" + count + ":" + (System.currentTimeMillis() - startTime));

        // 通过反射操作JavaBean的get/set方法
        Note gsNote = new Note();
        gsNote.setContent("1");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            gsNote = new Note();
            doSetter(gsNote, getSetter(Note.class, gsNote.getClass().getDeclaredField("content")), str + i);
        }
        System.out.println("get/set count:" + count + ":" + (System.currentTimeMillis() - startTime));


        // setAccessible方式
        Note accessNote = new Note();
        accessNote.setContent("1");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            accessNote = new Note();
            ReflectUtil.setFieldValue(accessNote, accessNote.getClass().getDeclaredField("content"), str + 1);
        }
        System.out.println("setAccessible count:" + count + ":" + (System.currentTimeMillis() - startTime));
    }
}

结果:
设置值

循环次数正常操作set方法反射setAccessible
10451
10000
100021
1000052
100001207
100000136529
100000020385154
100000002672965880
1000000002096296818928

获取值

循环次数正常操作get方法反射setAccessible
1065
10000
100020
1000071
100000304
100000211520
1000000288470
1000000007258719
1000000000728057083

总结

  1. 直接操作对象的方法是最快的。
  2. 1000次内三种方式的耗时相差不大,1000次后的耗时差距开始出现明显的差距。
  3. 如果需要频繁的进行反射操作,使用setAccessible会更高效。

文章如有错误,还望各位大佬不吝指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值