探究java反射取值与方法取值性能对比
由于我开发框架时,经常需要对象取值。常用的取值方式有:
- 反射取值
- 方法调用取值
环境
同一台电脑:
jdk 21.0.2
idea 2023.3.3
1. 测试代码(常用)
1.1 反射取值
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 方法调用
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 反射
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;}
结果
耗时:8
耗时:5
耗时:0
耗时:1
耗时:0
耗时:1
中途出现 0
不知道不知道是不是jvm优化
2.2 方法调用
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;}
结果:
耗时:9
耗时:8
耗时:5
耗时:4
耗时:3
耗时:4
2.3 测试结果
上面的结果是挑选了比较好的数据,不难看出,即便是缓存,也是反射优胜
。
3. 结论
对象取值,预先缓存反射对象,将会获得更快的取值速度。推荐使用反射取值