java序列化與反序列化(5)------反序列化時物件的建立方式
阿新 • • 發佈:2019-02-16
可以執行如下的程式碼進行測試:
我們思考在序列化時寫入位元組流中確實有類的全路徑名,從中我們可以獲得Class資訊,並可以通過呼叫建構函式的方式建立物件,但是我們在序列化時並不是將所有的域都序列化了,如果類存在某個建構函式中驗證了某些引數的合法性,如果不合法丟擲異常的這種邏輯,那麼呼叫建構函式建立物件就會直接丟擲異常。這樣想來也確實不能夠通過呼叫建構函式建立物件。當然了我們在序列化時並沒有要求被序列化的類,一定要提供無參的公共建構函式。這樣一分析在不涉及父子繼承關係的類進行反序列化時,是不太可能通過呼叫建構函式進行建立物件的。
/** * * @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資訊,並可以通過呼叫建構函式的方式建立物件,但是我們在序列化時並不是將所有的域都序列化了,如果類存在某個建構函式中驗證了某些引數的合法性,如果不合法丟擲異常的這種邏輯,那麼呼叫建構函式建立物件就會直接丟擲異常。這樣想來也確實不能夠通過呼叫建構函式建立物件。當然了我們在序列化時並沒有要求被序列化的類,一定要提供無參的公共建構函式。這樣一分析在不涉及父子繼承關係的類進行反序列化時,是不太可能通過呼叫建構函式進行建立物件的。