利用反射与注解生产高复用性代码
来源:互联网 发布:网络词f是什么意思 编辑:程序博客网 时间:2024/05/16 04:03
反射的作用
反射是java中的一大特性,反射在项目开发中的应用十分广泛,很多框架就是基于反射与注解来写,反射避免了大量重复性的代码,开发人员可以将精力更多的放在功能逻辑的实现,在项目开发中为开发人员带来极大的便利。反射的特性
通过反射:
1、可以拿到对象的成员变量,成员方法
2、可以利用反射构造对应类的对象,调用类中的方法
3、结合注解,可以获得类成员变量和成员方法更多的属性和信息反射举例
讲一下之前在工程中遇到的问题,在将数据保存到数据库前,需要对数据先进行加密处理,如果不利用反射,你是不是会用以下这种方法去实现
这是一个银行卡的实体类(经过简化):
public class BankCard { private int id; private String bank_name; private String card_num; public int getId() { return id; } public String getBank_name() { return bank_name; } public void setBank_name(String bank_name) { this.bank_name = bank_name; } public String getCard_num() { return card_num; } public void setCard_num(String card_num) { this.card_num = card_num; } //不利用反射,加密银行卡对象可能是这样的 public BankCard encryBankCard (String password,Context context) { BankCard encryBankCard=new BankCard(); encryBankCard.setBank_name(EncryptUtil.encryptAESAndroid(this.getBank_name(),password));encryBankCard.setCard_num(EncryptUtil.encryptAESAndroid(this.getCard_num(),password)); return encryBankCard; }}
像上面代码一样,在每次需要加密对象的时候,调用 bankCard.encryBankCard方法,这样是可以实现加密对象功能,可是仔细想想,对象中的成员变量不只是两三个,像encryBankCard.setCard_num(EncryptUtil.encryptAESAndroid(this.getCard_num(),password));
这样的语句要写多少遍啊!还有一个更需要考虑的问题,应用工程中像BankCard这样的实体类数不胜数,难道每次要加密对象的时候都为对象写一个类似的加密方法吗?若是如此,应用中的重复代码将会增多。像这样的实现方法,代码的可复用性算是比较差的。
现在,利用反射,来看看反射对工程中避免代码重复的贡献:
基于反射的原理,在EncryptUtil类中写一个高可复用性的工具方法
//加密类public class EncryptUtil { public static String encryptAESAndroid(String content, String password) { //省略此处代码 } //范型方法 public static <T> T encryObject(T initObject,String password){ Object copyObject=null; try { //利用反射新建一个新对象,这个对象用来封装加密数据 copyObject = initObject.getClass().newInstance(); //得到原始对象中声明的成员变量 Field[] fields=initObject.getClass().getDeclaredFields(); //开始遍历成员变量 for(Field field:fields){ //强制成员变量可访问,因这成员变量可能是private的 field.setAccessible(true); Object value; try { //取出成员变量的值 value = field.get(intiObject); //判断成员变量的属性 if(value instanceof String){ //这里只对String 类型的变量加密,因为服务器返回的数据都是字符串 field.set(copyObject, EncryptUtil.encryptAESAndroid((String)value, password)); } } catch (Exception e) { e.printStackTrace(); } } return (T) copyObject; } catch (InstantiationException e) { e.printStackTrace(); return null; } catch (IllegalAccessException e) { e.printStackTrace(); return null; } }}
以后数据需要保存时,就可以调用以上静态的范型方法EncryptUtil.encryObject(T initObject,String password) 来加密数据,可这样做就可以一劳永逸了吗?只根据反射来加密数据,在灵活性这方面,还是有所欠缺的。以上反射的代码,对所有String类的成员变量都进行了加密。若是有些成员变量不想加密,以上反射的代码就无法满足要求了。因为单纯用反射去反射对类的成员变量,只能拿到成员变量的值和类型,无法得到、该成员变量是否要进行加密。这个时候,java注解的作用就体现出来了,注解为反射提供更有用的信息,注解辅助反射,也是很多框架的实现原理和基础。
以下是自定义的一个简单的运行时注解(与反射结合使用的一般是运行时注解),该注解可添加在成员变量上:
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface EncryAnnotation { //默认是要加密 boolean isEncry()default true;}
在实体类中加入注解
public class BankCard { @EncryAnnotation(isEncry=false) private String bank_name; @EncryAnnotation(isEncry=true) private String card_num;}
将加密的范型方法做如下调整
//范型方法 public static <T> T encryObject(T initObject,String password){ Object copyObject=null; try { //利用反射新建一个新对象,这个对象用来封装加密数据 copyObject = initObject.getClass().newInstance(); //得到原始对象中声明的成员变量 Field[] fields=initObject.getClass().getDeclaredFields(); //开始遍历成员变量 for(Field field:fields){ //强制成员变量可访问,因这成员变量可能是private的 field.setAccessible(true); Object value; try { //取出成员变量的值 value = field.get(intiObject); //判断成员变量的属性 if(value instanceof String){ //这里只对String 类型的变量加密,因为服务器返回的数据都是字符串 //得到注解信息 EncryAnnotation annotation = field.getAnnotation(EncryAnnotation.class); //从注解中得知是否对该成员变量进行加密 if(annotation!=null&&annotation.isEncry()){ field.set(copyObject, EncryptUtil.encryptAESAndroid((String)value, password)); }else{ field.set(copyObject, (String)value); } } } catch (Exception e) { e.printStackTrace(); } } return (T) copyObject; } catch (InstantiationException e) { e.printStackTrace(); return null; } catch (IllegalAccessException e) { e.printStackTrace(); return null; } }}
根据项目的需要,可以为注解添加更多的字段,比如不同成员变量用不同的密码加密,就可以在为注解添加一个String password()的变量。
反射与注解的简要介绍就到此为止了。以上利用反射和注解讲解的是,加密前对象——->加密对象,然后存入数据库中。以此类推,从数据库获到数据,加密对象——>解密后对象,也可以利用反射与注解实现。
- 利用反射与注解生产高复用性代码
- 代码与生产计划
- 注解与反射
- 反射与注解
- 反射与注解
- 反射与注解
- 注解与反射
- 注解与反射
- java 注解与反射
- java反射与注解
- Java反射与注解
- JAVA反射与注解
- JAVA反射与注解
- 反射与注解
- Java注解详解,自定义注解,利用反射解析注解
- Java注解详解,自定义注解,利用反射解析注解
- Java注解详解,自定义注解,利用反射解析注解
- Java注解详解,自定义注解,利用反射解析注解
- 最适合程序员使用的图片压缩工具 pngquant
- JavaScript权威指南_148_第15章_脚本化文档_15.10-其他文档特性-查询选取的脚本
- 85. Maximal Rectangle
- SN7325多功能IO扩展驱动器学习
- 设计模式的学习记录1
- 利用反射与注解生产高复用性代码
- C#文件路径类
- c#post给http接口
- linux加固
- ViewPager 详解(一)---基本入门
- Eclipse连接JDBC数据库遇到的问题
- Algorithms—162.Find Peak Element
- word排版之长英文单词自动换行
- EXT,登录后点击backspace键会退回到登录页面,解决方法