黑马程序员-运行时通过反射复制对象

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

package com.itcast.test1;

import java.io.Serializable;

/**
 * javabean多用于封装属性,而很少具备某些特定的方法功能。
 * 试想,javabean的功能就是传递数据,那么类权限为共有也
 * 就不足为奇了。下面是标准javabean要遵守的一些规范:
 *1. 类访问权限为公有
 *2. 所有属性为私有
 *3. 每个字段对外提供setter方法和getter方法
 *4. 具备一个无参的构造方法
 */
public class Ball implements Serializable {
	//private static final long serialVersionUID = 1L;
	/**
	 * 实现序列化
	 * 要将某类的对象序列化,则该类必须实现Serializable接口,该接口
	 * 仅是一个标志,告诉JVM该类的对象可以被序列化。如果某类未实现Serializable接口,
	 * 则该类对象不能实现序列化。
	 */
	private String ballName;
	private int serialNumber;
	public Ball() {}
	public Ball(String ballName, int serialNumber) {
		super();
		this.ballName = ballName;
		this.serialNumber = serialNumber;
	}
	public String getBallName() {
		return ballName;
	}
	public void setBallName(String ballName) {
		this.ballName = ballName;
	}
	public int getSerialNumber() {
		return serialNumber;
	}
	public void setSerialNumber(int serialNumber) {
		this.serialNumber = serialNumber;
	}
	@Override
	public String toString() {
		return "Ball [ballName=" + ballName + ", serialNumber=" + serialNumber
				+ "]";
	}	
}

package com.itcast.test2;
import java.lang.reflect.*;

import com.itcast.test1.Ball;
public class RuntimeClone {

	/**
	 * 运行时复制对象
	 * 这个方法能够创建一个和参数 object 同样类型的对象,
	 * 然后把 object 对象中的所有属性拷贝到新建的对象中,
	 * 并将它返回 ,这个例子只能复制简单的 JavaBean
	 * @author shandawang
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Ball ball = new Ball("basketball",1);
		try {
			Ball cloneBall = (Ball)runtimeClone(ball);
			System.out.println(cloneBall.toString());
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 
	 * @param obj 要复制的对象
	 * @param args 构造函数参数列表
	 * @return 复制后的对象
	 */
	public static Object runtimeClone(Object obj) throws Exception {
		// 获取对象的完整类型
		Class<?> classType = obj.getClass();
		//System.out.println(classType.getName());
		// 使用默认构造方法创建一个实例
		/*
		 * 注意:若Ball类型定义了带参数的构造函数,则JVM不会定义默认构造函数
		 * 此时必须自定义不带参数的构造函数
		 */
		Object cloneObj = classType.getConstructor().newInstance();
		// 获取被复制对象的所有属性
		Field[] fields = classType.getDeclaredFields();
		String[] fieldNames = new String[fields.length]; // 属性名数组
		for(int i = 0;i < fields.length;i++) {
			// 获取属性名,通过反射调用对象的getters,setters
			fields[i].setAccessible(true);
			fieldNames[i] = fields[i].getName();
			// 属性名的首字母大写,获取方法名
			String firstUpperCaseLetter = fieldNames[i].substring(0, 1).toUpperCase();
			String getterMethodName = "get" + firstUpperCaseLetter + 
					fieldNames[i].substring(1,fieldNames[i].length()); // get方法名
			//System.out.println(getterMethodName);
			String setterMethodName = "set" + firstUpperCaseLetter +
					fieldNames[i].substring(1,fieldNames[i].length()); // set方法名
			//System.out.println(setterMethodName);
			Method getterMethod = classType.getMethod(getterMethodName);
			Method setterMethod = classType.getMethod(setterMethodName,fields[i].getType());
			// 调用原对象的get方法获取指定属性值
			Object fieldValue = getterMethod.invoke(obj);
			// 调用复制对象的set方法设定指定属性值
			setterMethod.invoke(cloneObj,fieldValue);
		}
		return cloneObj;
	}
}

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值