1. 程式人生 > >java序列化與反序列化(5)------反序列化時物件的建立方式

java序列化與反序列化(5)------反序列化時物件的建立方式

可以執行如下的程式碼進行測試:
/**
 * 
 * @author yujie.wang
 *
 */
public class CreateObjectTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//createByNew();
		String classFullPathName = "com.yujie.createbean.Player";
		createByReflect1(classFullPathName);
		createByReflect2();
		createByReflect3();
	}
	
	/**
	 * 通過new關鍵字建立物件 一定顯示地呼叫建構函式
	 */
	public static void createByNew(){
		Player yujie = new Player(20,"yujie.wang");
		yujie.introduceMyself();
	}
	
	/**
	 * 通過反射Class.forName(classFullPathName).newInstance()建立物件
	 * 一定要呼叫預設的無參建構函式
	 * @param classFullPathName
	 */
	public static void createByReflect1(String classFullPathName){
		if(classFullPathName == null || classFullPathName.isEmpty()){
			System.out.println("classFullPathName == null || classFullPathName.isEmpty()");
		}
		Player yujie = null;	
		try {
			yujie = (Player)Class.forName(classFullPathName).newInstance();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		if(yujie != null){
			yujie.introduceMyself();
		}else {
			System.out.println("yujie == null");
		}
	}
	
	/**
	 * 通過反射Class.forName(classFullPathName).newInstance()建立物件
	 * 一定要呼叫預設的無參建構函式
	 */
	public static void createByReflect2(){
		try {
			Player yujie = Player.class.newInstance();
			yujie.introduceMyself();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 通過反射Player.class.getConstructor(int.class,String.class).newInstance()建立物件
	 * 一定要呼叫相應的建構函式
	 */
	public static void createByReflect3(){
		try {
			Constructor<Player> c = Player.class.getConstructor(int.class,String.class);
			Player yujie = c.newInstance(20,"yujie.wang");
			yujie.introduceMyself();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

我們思考在序列化時寫入位元組流中確實有類的全路徑名,從中我們可以獲得Class資訊,並可以通過呼叫建構函式的方式建立物件,但是我們在序列化時並不是將所有的域都序列化了,如果類存在某個建構函式中驗證了某些引數的合法性,如果不合法丟擲異常的這種邏輯,那麼呼叫建構函式建立物件就會直接丟擲異常。這樣想來也確實不能夠通過呼叫建構函式建立物件。當然了我們在序列化時並沒有要求被序列化的類,一定要提供無參的公共建構函式。這樣一分析在不涉及父子繼承關係的類進行反序列化時,是不太可能通過呼叫建構函式進行建立物件的。