博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决实体类噩梦:联合实体类(Java反射+泛型实际应用)
阅读量:6234 次
发布时间:2019-06-22

本文共 4638 字,大约阅读时间需要 15 分钟。

       小菜提到的实体类,即项目中业务或者数据库表的映射,貌似也可以称为模型,不同的语言中叫法不同吧!!

       举个例子,比如在某个Web页面中,表单上有大量的数据需要提交,如果是初学者,很可能这样接收参数:

       String param1;String param2;String param3;……

       这样做的坏处很多,比如:代码会显得很乱,可能会出现大量重复代码,最主要的就是没有做到面向对象的“封装性”,导致程序不容易维护。

       由此,聪明的程序员们提出了实体类的概念,也就是用类来封装业务所需要的数据。

       public class User {

       private String uid;

       private String pwd;

       public String getUid() {

              return uid;

       }

       public void setUid(String uid) {

              this.uid = uid;

       }

       …..

       }

       这样一来,我们在保存数据时,只需创建一个对象,然后通过“.”的方式来访问对象的属性,提高扩展性、提高复用性、代码简洁等等好处不言而喻。

       在实际使用中,实体类往往是和某个业务或者数据库表相对应的,看起来很简单,但随着需求的复杂化,业务和业务之间可能会交叉,表和表之间可能会联合查询。

       这样一来,以前一一对应的实体类,便无法满足需求,因为某个实体类中可能找不到我们需要的属性,但是它却在另一个实体类中,而我们又不想随便在某个实体类中添加一个毫不相关的属性,因为这样做可能会打破类的职责单一原则。

       因此,我们不得不再新建一个实体类ClassAAndClassB,这个实体类包含了类A和类B的所有属性,对于稍有经验的程序员来说,这绝对是个噩梦,因为组合的可能性是在是太多,而且可能是很多个实体组合,等待我们的将是无数的实体类,导致程序混乱不堪。

       小菜一直苦于此事,今天终于通过Java的反射和泛型写了一个“联合实体类”。

       通过这个联合实体类,可以把任意多个实体类融合成一个实体类。

联合实体类代码:

1 import java.lang.reflect.Method;  2 import java.util.List;  3   4 /**  5  * 联合实体类  6  * @author 杨元  7  *  8  */  9 public class UniteEntity { 10      11     //联合实体对象集合 12     List entitys = null; 13     //方法名称 14     String fnName = ""; 15     //方法对象 16     Method method = null; 17      18     /** 19      * 构造方法 20      * @param entitys 需要联合的实体对象集合 21      */ 22     public UniteEntity(List entitys){ 23         this.entitys = entitys; 24     } 25      26     /** 27      * 获取某个取值方法 28      * @param fnName 方法名称 29      * @return 该取值方法返回值类型 30      */ 31     public Class getFunction(String fnName){ 32         //保存方法名称 33         this.fnName = fnName; 34         //查找方法 35         Method m = findMethod(); 36         //判断方法是否存在 37         if(m != null){ 38             //获取目标方法的返回值类型 39             Class type = m.getReturnType(); 40             //保存取值方法对象 41             method = m; 42             //返回该取值方法返回值类型 43             return type; 44         }else{ 45             return null; 46         } 47     } 48      49     /** 50      * 获取某个赋值方法 51      * @param fnName 方法名称 52      * @return 该赋值方法参数类型 53      */ 54     public Class setFunction(String fnName){ 55         //保存方法名称 56         this.fnName = fnName; 57         //查找方法 58         Method m = findMethod(); 59         //判断方法是否存在 60         if(m != null){ 61             //获取目标方法的参数类型 62             Class type = m.getParameterTypes()[0]; 63             //保存赋值方法对象 64             method = m; 65             //返回该赋值方法参数类型 66             return type; 67         }else{ 68             return null; 69         } 70     } 71      72     /** 73      * 调用某个方法,为属性赋值 74      * @param 
赋值方法的参数类型 75 * @param c 76 * @param value 值内容 77 */ 78 public
void setValue(Class
c,T value){ 79 //遍历实体类集合 80 for(Object o : entitys){ 81 //出错继续执行 82 try{ 83 method.invoke(o, value);             break; 84 }catch(Exception ex){} 85 } 86 } 87 88 /** 89 * 调用某个方法,取得属性的值 90 * @param
取值方法的返回值类型 91 * @param c 92 * @return 取得值的内容 93 */ 94 public
T getValue(Class
c){ 95 //遍历实体类集合 96 for(Object o : entitys){ 97 //出错继续运行 98 try{ 99 //由于invoke返回的是Object类型,因此要强制转换成T类型100 return (T)method.invoke(o);101 }catch(Exception ex){}102 }103 return null;104 }105 106 /**107 * 从实体对象集合中查找某个方法108 * @return 方法对象109 */110 private Method findMethod(){111 //遍历集合,寻找方法112 for(Object o : entitys){113 //保证出错能继续运行114 try{115 //获取对象所有公有方法116 Method[] methods = o.getClass().getMethods();117 118 //遍历方法119 for(Method m : methods){120 //匹配是否有目标方法121 if(fnName.equals(m.getName())){122 //返回方法对象123 return m;124 }125 }126 }catch(Exception ex){}127 }128 return null;129 }130 }

 

调用方法:

 

1 //创建一个对象集合 2 List list = new ArrayList(); 3  4 //将需要融合的实体类填入集合 5 list.add(new User()); 6 list.add(new Enterprise()); 7  8 //创建联合实体类对象 9 UniteEntity ue = new UniteEntity(list);10 11 int i = 109;12 13 //调用实体类中方法名为setEnno的方法(赋值方法),并给一个参数i14 ue.setValue(ue.setFunction("setEnno"), i);15 //调用实体类中方法名为getEnno的方法(取值方法),并打印返回值16 System.out.println(ue.getValue(ue.getFunction("getEnno")));

 

说明:

 

       用法很简单,创建联合实体对象的时候必须传入需要融合的实体对象集合。

       如果想调用的方法是取值方法,则先调用联合实体对象的getFunction方法,参数是方法的名称,一定要写对!!最好是复制!!这个步骤会查找到指定的方法,并且确定该方法的返回值类型,然后把getFunction方法的返回值作为参数,调用联合实体对象的getValue方法,即可取得属性值。

       如果想调用的方法是赋值方法,则先调用联合实体对象的setFunction方法,同理,该方法会确定参数的类型,把setFunction方法的返回值作为参数,调用联合实体对象的setValue方法,再加上需要赋给的值,即可给属性赋值。

       由于使用了泛型技术,所以本类比较安全、稳定。调用赋值方法时,如果传入的值和方法的参数类型不同,直接赋值失败,不会抛出异常;调用取值方法时,直接对取出来的值进行强制类型转换即可,无需验证数据类型(例如:int[] items = (int[])ue.getValue(ue.getFunction("getEmp"));)。

注意事项:

 

       使用本类肯定会降低程序效率,慎重使用。

       本类只支持带有一个参数的属性赋值方法。

       如果多个实体类中有重复的方法名称,则默认使用的是在集合中靠前的那个实体类的方法。

写在后面的话:

 

       本文只是提供一种思路,肯定不是最好的解决方案,也不一定能满足读者的需求,高手勿喷。。。

附:完整演示代码

 

       

 

 

转载地址:http://zlqna.baihongyu.com/

你可能感兴趣的文章
李笑来哭了,韭菜财经们笑了
查看>>
《快学 Go 语言》第 15 课 —— 反射
查看>>
既生 Redis 何生 LevelDB ?
查看>>
给自己出的iOS面试题
查看>>
2.1.5 Python元类深刻理解(metaclass)
查看>>
Node.js 系列 - 搭建静态资源服务器
查看>>
ScratchView:一步步打造万能的 Android 刮奖效果控件
查看>>
万绿从中一点蓝,一篇无用的文章
查看>>
如何在1到100的整数数组上找到缺失的数字
查看>>
BBC 新闻数据可视化 Cookbook
查看>>
力扣(LeetCode)22
查看>>
一秒搭建gitbook
查看>>
react 与 Vue的一些比较
查看>>
vue-cli3环境变量与分环境打包
查看>>
前端爬坑之旅--echarts渲染时canvas变为100px
查看>>
C#中的Singleton模式
查看>>
git 常用命令
查看>>
在Windows下,用Hexo搭建博客
查看>>
Element组件引发的Vue中mixins使用,写出高复用组件
查看>>
【Linux系统编程】普通用户绑定(bind)特权端口
查看>>