最近和Java的反射打交道比较多一点,可能是因为自己以后的方向是架构师的缘故吧,他们主要搞业务。我能也就搞架构,整天画一些流程图。
虽然对于只有一年实习经验的我,不知道这样是否好,但是我还是那句话,不论好坏,先走着,毕竟也能学到很多东西,而且还可以锻炼自己的思维能力。
表达能力,因为自己的产品做的再好,你就是表达不出来,说不出来优势,那么你就败了。
先创建一个实体类User
package com.mine.practice.copyproperty.entity; /** * * @author 2014-11-6 上午10:28:10 * @version V1.0 */ public class User { private int id; private String name; private String pwd; private double idG; public double getIdG() { return idG; } public void setIdG(double idG) { this.idG = idG; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.mine.practice.copyproperty.test; import java.lang.reflect.Field; import com.mine.practice.copyproperty.entity.User; /** * 属性拷贝 * @author 2014-11-6 上午10:29:32 */ public class TestCopyProperty { /** * 业务需求: * 对于某些业务进行某个或某些类的数据更新时,只想更新该类的部分字段,其它字段还使用之前的值。 * * 遇到问题: * 当有些业务需要增加或减少某个类的字段个数、修改字段名称时,前台可能只需要修改一个地方就可以解决了。 * 但是后台由于采用的事件的方式进行处理,所以会有多个地方使用,修改起来比较困难。 * * 主要解决问题: * 即使字段个数或者字段名称修改后后台代码也不需要修改。 * * 解决方案: * 在借鉴之前的解决方案的基础上进行了修改。 * 通过遍历该类的所有属性,然后获取新类的属性值,如果新类的属性值不为null、空字符串、基本类型的默认值 * 则把新的对象的属性值赋值给老的对象属性 * * 优点:1、即使增加或者修改字段个数后台也不需要改动 * 2、即使修改字段名称或者类型后台也不需要改动 * * 缺点:1、会遍历一个类的所有属性,并且判断新对象的属性值:是否存在以及是否为默认值。批量数据时性能会有些差 * 2、由于基本数据类型会有默认值,所以框架不知道这个字段的值到底要不要修改到新的对象上面。 * * * @author 2014-11-6 上午11:01:03 * @param args * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @modificationHistory=========================逻辑或功能性重大变更记录 * @modify by user: {修改人} 2014-11-6 * @modify by reason:{原因} */ public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { //老对象 User oldUser = new User(); oldUser.setId(1); oldUser.setName("name1"); oldUser.setPwd("pwd1"); oldUser.setIdG(1.2); System.out.println("数据库中的老对象"); print(oldUser); //新对象 User newUser = new User(); newUser.setName("name2"); System.out.println("前台传递过来的新对象"); print(newUser); //功能需求 //把之前的老对象的id和name修改掉,但是pwd不需要修改 copyProperty(oldUser,newUser); System.out.println("----------老对象被修改后-------------"); print(oldUser); } /** * * @author 2014-11-6 上午11:26:36 * @param oldUser * @param newUser * @throws NoSuchFieldException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException * @modificationHistory=========================逻辑或功能性重大变更记录 * @modify by user: {修改人} 2014-11-6 * @modify by reason:{原因} */ @SuppressWarnings("rawtypes") private static void copyProperty(User oldUser,User newUser) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException{ //新的class Class newClass = newUser.getClass(); //老的class Class oldClass = oldUser.getClass(); //该类所有的属性 Field[] newFields = newClass.getDeclaredFields(); //新的属性 Field newField = null; //老的属性 Field oldField = null; for(Field f : newFields){ //类中的属性名称 String fieldName = f.getName(); //通过属性名称获取属性 newField = newClass.getDeclaredField(fieldName); //获取属性的值时需要设置为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。 //值为 false 则指示反射的对象应该实施 Java 语言访问检查。 newField.setAccessible(true); //根据属性获取对象上的值 Object newObject = newField.get(newUser); //过滤空的属性或者一些默认值 if (isContinue(newObject)) { continue; } oldField = oldClass.getDeclaredField(fieldName); oldField.setAccessible(true); oldField.set(oldUser, newObject); } } /** * 是否跳出本次循环 * @author 2014-11-6 上午11:37:22 * @param object * @return true 是 有null或者默认值 * false 否 有默认值 */ private static boolean isContinue(Object object){ if (object == null || "".equals(object)) { return true; } String valueStr = object.toString(); if ("0".equals(valueStr) || "0.0".equals(valueStr)) { return true; } return false; } /** * * @author 2014-11-6 上午10:57:32 * @param user */ private static void print(User user){ System.out.println("id: "+user.getId()); System.out.println("name: "+user.getName()); System.out.println("pwd: "+user.getPwd()); System.out.println("idG: "+user.getIdG()); } }
原文:http://blog.csdn.net/baidu_18607183/article/details/40866257