黑馬程序員-運行時通過反射覆制對象

----------- 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學習型技術博客、期待與您交流! ------------


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章