import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class TestClass implements Serializable{
private static final long serialVersionUID = 0L;
public TestClass() throws Exception {
throw new Exception("哎呀媽呀,異常啦!!!!");
}
public static void main(String[] args) throws Exception {
byte[] head = { -84, -19, 0, 5, 115, 114, 0 };
byte[] ass = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 120, 112 };
String name = TestClass.class.getName();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(head);
baos.write(name.length());
baos.write(name.getBytes());
baos.write(ass);
baos.flush();
baos.close();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
TestClass o = (TestClass) ois.readObject();
ois.close();
System.out.println("創建對象: " + o);
}
}
看到這裏先彆着急執行,先看看.你覺得能夠正常運行嗎? 結果是什麼? -----------------------------------------------------------------------------------
運行結果: 創建對象: TestClass@743399
1.使用new關鍵字 2.使用clone方法 3.反射機制 4.反序列化
其中1,3都會明確的顯式的調用構造函數
2是在內存上對已有對象的影印 所以不會調用構造函數
4是從文件中還原類的對象 也不會調用構造函數
上述代碼就是反序列化的結果
serialization is an extralinguistic mechanism for creating objects. Whether
you accept the default behavior or override it, deserialization is a “hidden constructor”
with all of the same issues as other constructors.
大體的意思是反序列化有一定的風險.破壞了封裝.相當於一個隱藏的構造器.
2、“this”是作爲實例構造器的第一個實際參數傳入的。
Java反序列化實際上是調用了基類的構造方法.
ObjectStreamClass中調用ReflectionFactory.newConstructorForSerialization(cl, cons);
- cons = reflFactory.newConstructorForSerialization(cl, cons);
根據cl參數(TestClass類的Class對象)和cons參數(基類Object的構造器)創建了一個新的構造器
打印生成的構造器對象,輸出信息爲public java.lang.Object(),表面生成的構造器是TestClass父類Object的無參構造器.
但是調用newInstance()的結果卻產生了TestClass類的對象.(おかしい......)
ReflectionFactory.newConstructorForSerialization()例子
- Constructor superCons = TestClass.class.getSuperclass().getConstructor();
- System.out.println(superCons);
- ReflectionFactory reflFactory = ReflectionFactory.getReflectionFactory();
- Constructor c = reflFactory.newConstructorForSerialization(TestClass.class,superCons);
- System.out.println(c.newInstance());
Constructor superCons = TestClass.class.getSuperclass().getConstructor();
System.out.println(superCons);
ReflectionFactory reflFactory = ReflectionFactory.getReflectionFactory();
Constructor c = reflFactory.newConstructorForSerialization(TestClass.class,superCons);
System.out.println(c.newInstance());
- public java.lang.Object()
- TestClass@fd13b5
通過基類的方法調用生成了子類.繞開了TestClass類的構造方法.生成了看似不可能存在的TestClass對象
-----------------------------------------------------------------------------------
感謝FX,之前一篇關於構造器的詳細論述.傳送門http://rednaxelafx.iteye.com/blog/652719
FX寫的關於本篇的更詳細講解在這裏,傳送門http://rednaxelafx.iteye.com/blog/850082