在特定场景下,使用函数式编程替代反射,可以简化代码,提高代码执行效率。
之前工作中遇到一个场景,不定长度的数组,需要将值依次赋给对象的某些字段。当时的解决方案是使用反射,对函数式编程理解更深刻之后,可以使用反射替代。
反射需要解析字节码,效率不高;需要处理受检异常;代码较多。推荐使用函数式编程。
测试代码如下:
1 package demo;
2
3 import java.lang.reflect.InvocationTargetException;
4 import java.lang.reflect.Method;
5 import java.util.Arrays;
6 import java.util.List;
7 import java.util.function.BiConsumer;
8 import java.util.stream.IntStream;
9
10 public class Test01 {
11
12 static String[] arr = { "str01", "str02", "str03", "str04", "str05", "str06", "str07", "str08", "str09", "str10" };
13
14 static List<BiConsumer<Item, String>> biConsumers = Arrays.asList(Item::setVar1, Item::setVar2, Item::setVar3,
15 Item::setVar4, Item::setVar5, Item::setVar6, Item::setVar7, Item::setVar8, Item::setVar9, Item::setVar10);
16
17 public static void main(String[] args) {
18 long start = System.currentTimeMillis();
19 IntStream.range(0, 10000).forEach(i -> testReflect());
20 long end = System.currentTimeMillis();
21 System.out.println(end - start);
22
23 long start1 = System.currentTimeMillis();
24 IntStream.range(0, 10000).forEach(i -> testMethodReference());
25 long end1 = System.currentTimeMillis();
26
27 System.out.println(end1 - start1);
28 }
29
30 static void testReflect() {
31 Item item = new Item();
32
33 try {
34 Class<?> clazz = Class.forName("demo.Item");
35 for (int i = 0; i < arr.length - 1; i++) {
36 Method method = clazz.getMethod("setVar" + (i + 1), String.class);
37 method.invoke(item, arr[0]);
38 }
39
40 } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException
41 | IllegalArgumentException | InvocationTargetException e) {
42 e.printStackTrace();
43 }
44 }
45
46 static void testMethodReference() {
47 Item item = new Item();
48
49 for (int i = 0; i < arr.length; i++) {
50 biConsumers.get(i).accept(item, arr[i]);
51 }
52 }
53 }
一个简单的基准测试结果:速度差了10倍
1 package demo;
2
3 public class Item {
4 private String var1;
5 private String var2;
6 private String var3;
7 private String var4;
8 private String var5;
9 private String var6;
10 private String var7;
11 private String var8;
12 private String var9;
13 private String var10;
14
15 public String getVar1() {
16 return var1;
17 }
18
19 public void setVar1(String var1) {
20 this.var1 = var1;
21 }
22
23 public String getVar2() {
24 return var2;
25 }
26
27 public void setVar2(String var2) {
28 this.var2 = var2;
29 }
30
31 public String getVar3() {
32 return var3;
33 }
34
35 public void setVar3(String var3) {
36 this.var3 = var3;
37 }
38
39 public String getVar4() {
40 return var4;
41 }
42
43 public void setVar4(String var4) {
44 this.var4 = var4;
45 }
46
47 public String getVar5() {
48 return var5;
49 }
50
51 public void setVar5(String var5) {
52 this.var5 = var5;
53 }
54
55 public String getVar6() {
56 return var6;
57 }
58
59 public void setVar6(String var6) {
60 this.var6 = var6;
61 }
62
63 public String getVar7() {
64 return var7;
65 }
66
67 public void setVar7(String var7) {
68 this.var7 = var7;
69 }
70
71 public String getVar8() {
72 return var8;
73 }
74
75 public void setVar8(String var8) {
76 this.var8 = var8;
77 }
78
79 public String getVar9() {
80 return var9;
81 }
82
83 public void setVar9(String var9) {
84 this.var9 = var9;
85 }
86
87 public String getVar10() {
88 return var10;
89 }
90
91 public void setVar10(String var10) {
92 this.var10 = var10;
93 }
94 }
View Code
另外,当前场景可以通过存储Method的集合,避免每次循环都重新执行反射,提高效率,但无法避免受检异常。也可以通过if-else判断,会导致代码繁杂,可避免异常处理。
两者都不如方法引用简洁、高效。