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     }

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

写在最后

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

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

时间: 2024-10-26 19:21:42

Java基础----jdk1.8 反射实验的相关文章

Java基础13:反射与注解详解

Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Oracle官方对反射的解释是 Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fi

Java 基础篇之反射

Java 基础篇之反射 反射# 使用反射获取程序运行时的对象和类的真实信息. 获取 Class 对象# 每个类被加载之后,系统会为该类生成一个对应的 Class 对象,通过该 Class 对象可以访问到 JVM 中的这个类. 使用 Class 类的 forName(String clazzName) 静态方法.字符串参数的值是某个类的全限定类名,必须包含完整的包名 调用某个类的 class 属性 调用某个对象的 getClass() 方法.该方法是 java.lang.Object 类中的一个方

学习Spring必学的Java基础知识(1)----反射

引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Java基础知识,希望对大家有所帮助.): [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http://www.iteye.com/topic/1123293 [3] 属性

学习Spring必学的Java基础知识(1)----反射(转)

引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓"登高必自卑,涉远必自迩".以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Java基础知识,希望对大家有所帮助.): [1] Java反射知识-->Spring IoC :http://www.iteye.com/topic/1123081 [2] Java动态代理-->Spring AOP :http://www.iteye.com/topic/1123

java基础--接口与反射总结

一.接口 接口中所有的方法默认public static final,不必再写. 接口中可以定义常量,但不能含有实例域.在java SE8之前,不能在接口中实现方法. 一个类可以实现多个方法implements 接口1,接口2...多个接口之间用","隔开. 克隆:要实现克隆先实现Cloneable接口,重新定义clone方法,并指定public修饰符. 默认clone是浅克隆,要实现深克隆需要自己重写clone. 所有的数组类型都有一个public的clone方法. 二.反射 概念:

java基础11(反射)

1.类加载器 a.类的加载: 定义:当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. 一个类在加载过程中的三部曲: A.加载 : 就是指将class文件读入内存,并为之创建一个Class对象. 任何类被使用时系统都会建立一个Class对象. B.连接: 验证 是否有正确的内部结构,并和其他类协调一致 准备 负责为类的静态成员分配内存,并设置默认初始化值 解析 将类的二进制数据中的符号引用替换为直接引用 C.初始化 b.类的加载时机:

【Java基础总结】反射

1. 什么是反射 Class.Method.Field.Constructor,它们是反射对象.它们是类.方法.成员变量.构造器,在内存中的形式. 也就是万物皆对象!类是类型.方法是类型.成员变量是类型.构造器也是类型. 可以把Class当作类的元神:Method是方法的元神:Field是成员的元神:Constructor是构造器的元神. 得到了元神就可以来操作宿主. 2. 获取Class类的对象 Class表示一个类型,即描述类的类型. * 类名.class:Class c1 = Object

Java基础加强之反射

1.什么是反射? 反射其实就是动态的加载类,我们在写JDBC的时候加载驱动Class.forName("xxx")时就涉及到了反射. 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 2.反射机制能做什么? 1. 在运行时判断任意一个对象的所属的类Class. 2. 在运行时判断构造任意一个类的对象Constructor. 3. 在运行

Java基础知识总结--反射

反射:在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识.这个信息跟踪着每一个对象所属的类.虚拟机利用运行时类型信息选择相应的方法执行. Java反射机制是在系统运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为Java的反射机制. 要想解剖一个类,必须先要获取到该类的字节码文件对象.使用Class类中的方法,可以获取到每一个字节码文件对应的Class类