首页 > 代码库 > Java基础----jdk1.8 反射实验

Java基础----jdk1.8 反射实验

(写在最前:还没入门的搬砖工的一本正经的胡说八道)

引言:  最近做到的项目中,需要给对接方提供一个公共接口,根据对方传入的XML文件的rootelement分发调用接口,最简单的使用if-else if 模式,但是看着实在太蠢。

场景一:需要根据关键字,进行接口分发

使用if-else模式缺点:

  1. 看着蠢
  2. 不易阅读(个人观点)
  3. 不易维护
  4. balabala...不想编了,就是看着不爽

如果只有一两个方法还好,如果方法多了,额。。。如下,自行体会。

 1 public class TestMethod {
 2 
 3     public Object dispatchMethod(String name, String data) {
 4         Object obj = null;
 5 
 6         if ("methodA".equal(name)) {
 7             obj = methodA(data);
 8         } else if ("methodB".equal(name)) {
 9             obj = methodB(data);
10         } else if (...) {
11             ...
12         }
13         return obj;
14     }
15 
16     private Object methodA(String data) {
17         ...
18     }
19 
20     private Object methodB(String data) {
21         ...
22     }
23 
24     ...
25 }

那么步入正题,我才用的反射模式,匹配目标方法,我认为可以降低维护和阅读成本

开发环境:jdk1.8

实现代码:

  • 定义目标方法枚举,包含rootelement信息,调用方法说明,目标方法targetName
 1 public enum MethodEnum {
 2 
 3     METHODA("MethodA","调用方法A","methodA"),
 4     METHODB("MethodB","调用方法B","methodB"),
 5     ;
 6     
 7     @Getter
 8     private String code; //rootelement
 9     
10     @Getter
11     private String message; 
12     
13     @Getter
14     private String name; //目标方法名
15 
16     private MethodEnum (String code,String message,String name) {
17         this.code = code;
18         this.message = message;
19         this.name = name;
20     }
21     
22     public static MethodEnum fromCode(String code) { //根据传入code,筛选目标方法
23         for (DockingFliggyHotelEnum p : DockingFliggyHotelEnum.values()) {
24             if(p.code.equalsIgnoreCase(code)) {
25                 return p;
26             }
27         }
28         return null;
29     } 
32 }
  • 定义反射方法工具类
 1 /**
 2  *  定义工具类 
 3 **/
 4 public class MethodUtil {
 5 
 6     public static Method getTargetMethod(Class clazz, String methodName) {
 7         Method[] methods = clazz.getDeclaredMethods(); //获取所有方法,包含private
 8         if (methods != null && methods.length > 0) {
 9             String regEx  = "^" + methodName +"$";//获取所要查找到的方法名称要匹配此正则
10             Pattern pattern = Pattern.compile(regEx);
11             for (Method method : methods) {
12                 Matcher matcher = pattern.matcher(method.getName());
13                 boolean rs = matcher.find();
14                 if(rs){
15                     return method;
16                 }
17             }
18         }
19         return null;
20     }
21 
22     public static Object executeTargrtMethod(Class clazz, String methodName, String xmlData) {
23         Object obj = null;
24         try {
25             Method method = getTargetMethod(clazz, methodName);
26             obj = method.invoke(clazz, xmlData);
27         } catch (Exception e) {
28             
29         }
30         return obj;
31     }
32 
33 }
  • 具体分发
 1 public class TestDispatch {
 2 
 3     public Object dispatch(String root, String xml) {
 4         String name = MethodEnum.fromCode(root).name;
 5         Object obj = executeTargrtMethod(this.getClass(), name, xml)
 6         return obj;
 7     }
 8 
 9     private Object methodA(String xml) {
10         Object obj = null;
11         ...
12         return obj;
13     }
14 
15     private Object methodB(String xml) {
16         Object obj = null;
17         ...
18         return obj;
19     }
20 
21     ...
22 }

对于业务代码结构清晰明了,是不是看着爽多了。

对于类似的场景很多,都可以使用反射机制。

场景二:项目中多处需要大批量插入数据,提取一个公共方法,减少代码行数,何乐而不为呢?

对了,顺便说一下这个批量插入方法,数据库使用mysql,项目框架springboot,jdk1.8,5000条数据插入一次,耗时0.8s左右。

 1    /**
 2      * @param batchCount 一次批量插入数据量
 3      * @param target 目标方法关键字
 4      * @param list 需要插入的大批量数据
 5      * @throws Exception
 6      */
 7     public static void batchInsert(Class clazz, int batchCount, String target, List<?> list) throws Exception{
 8         Method method = getTargetMethod(target);
 9         int batchLastIndex = batchCount - 1;//每批最后一个的下标
10         for(int index = 0; index < list.size()-1;){
11             if(batchLastIndex > list.size()-1){
12                 batchLastIndex = list.size() - 1;
13                 if (method != null) {
14                     method.invoke(clazz,list.subList(index, batchLastIndex));
15                 }
16                 break;//数据插入完毕,退出循环
17             }else{
18                 if (method != null) {
19                     method.invoke(clazz,list.subList(index, batchLastIndex));
20                 }
21                 index = batchLastIndex + 1;//设置下一批下标
22                 batchLastIndex = index + (batchCount - 1);                
23             }                
24         }
25     }

实验结束,代码分析下次在写了。

写在最后

代码是伪代码,可能啥地方写得不对,欢迎指正

对于以上两种场景,我目前只能想到这种方法。。。如果你有更好的,欢迎来怼我

Java基础----jdk1.8 反射实验