使用Java对两个对象的属性进行拷贝

最近和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());
	}
}

功能简单,但是学习到了一些新知识还是很开森的。

时间: 2024-08-09 06:32:26

使用Java对两个对象的属性进行拷贝的相关文章

java比较两个对象是否相等的方法

java比较两个对象是否相等直接使用equals方法进行判断肯定是不会相同的. 例如: Person  person1  =new Person("张三"); Person  person2  =new Person("张三"); boolean  falg = person1.equals(person1); falg 的值是false; 如果要判断两个对象相同就需要重写父类的equals方法和hashCode方法: 这时再次测试时falg的值就是true.

Java中对比两个对象中属性值[反射、注解]

在Java中通常要比较两个对象在修改前与修改后的值是否相同,一般我们采用的是反射技术获取对象的get方法[或其他的方法]获取值并做比较.如果系统将修改的属性名称也显示出来,这样就能更直观的显示类中的哪一个属性的值被修改了.然后Java中只能获取属性的名称,也就是英文标识的属性名,但是一般我们都会在属性后面添加属性的注释,但是Java不提供注释获取的方法.所以我们只能使用另外一种方式来将属性和属性注释关联起来,这就是Java中的@Annotation. public static  Map<Str

Java获取未知类型对象的属性

获取未知类型对象的属性通常有两种方式: 一是通过自定义注解的方式,通过获取被注解的属性从而获取属性的值,这种方式也是Spring参数注入的重要实现手段 二是通过反射获取属性的名称,通过属性名从而获取属性,这种方式在开发时是比较简便易实现的. 一.关于注解 1.自定义注解 首先定义一个@interface类型的注解接口 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ClassBean

利用Java反射实现JavaBean对象相同属性复制并初始化目标对象为空的属性的BeanUtils

有时遇到将数据传输对象转换成JSON串会将属性值为空的属性去掉,利用Java反射实现JavaBean对象数据传输对象的相同属性复制并初始化数据传输对象属性为空的属性,然后转换成JSON串 package com.banksteel.util; import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Arrays;import java.ut

java 反射实现不同对象相同属性值复制

1.此方法会过滤final字段 2.此方法会过滤对象字段 3.此方法会兼容同对象之间.不同对象之间属性值复制 package com.bin.design.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; import com.bin.des

java比较两个对象是否相等?

1.判断两个对象是否是同一个引用对象则用==,"=="比的是地址.因为如果地址相同,则就是同一个对象(java中如果两对象(obj1,obj2)相等,那么在修改obj2的时候,obj1的值也会改变.其实相当于内存中只有一个对象,而obj1和obj2连个变量都指向同一个对象.)2.obj1.equals(Object obj2),用来判断两个对象是否相等.(如果两个变量引用的是两个不同地址的对象,即使对象的内部参数都是一样的,系统也会认为是不同的两个对象,所以要用equals)

java 对list中对象按属性排序

实体对象类 --略 排序类----实现Comparator接口,重写compare方法 package com.tang.list; import java.util.Comparator; public class Mycompera implements Comparator<Student> { @Override    public int compare(Student o1, Student o2) {        if (o1.getSid() > o2.getSid()

Java判断两个对象是否相等的规则

Object类中的equals方法用于检测一个对象是否等于另外一个对象.在Object类中,这个方法将判断两个对象是否具有相同的引用.如果两个对象具有相同的引用,它们一定是相等的.从这点上看,将其作为默认操作也是合情合理的.然而对于多数类来说,这种判断并没有什么意义.例如,采用这种方式比较两个PrintStream对象是否相等就完全没有意义.然而,经常需要检测两个对象状态的相等性,如果两个对象的状态相等,就认为这两个对象是相等的. 例如,如果两个雇员对象的姓名.薪水和雇佣日期都一样,就认为它们是

Java 判断两个对象是否相等

一.使用 == 与 equals == : 它的作用是判断两个对象的地址是不是相等.即,判断两个对象是不是同一个对象.(基本数据类型==比较的是值,引用数据类型==比较的是内存地址) equals() : 它的作用也是判断两个对象是否相等.但它一般有两种使用情况: 情况1:类没有覆盖equals()方法.则通过equals()比较该类的两个对象时,等价于通过"=="比较这两个对象. 情况2:类覆盖了equals()方法.一般,我们都覆盖equals()方法来两个对象的内容相等:若它们的