我正在閱讀Java中的思考第4版。 有描述transient
領域的系列化一個奇怪的解決方法:瞬時字段的Java序列化
import java.io.*;
public class SerializationTest implements Serializable {
private String firstData;
//transient field, shouldn't be serialized.
transient private String secondData;
public SerializationTest(String firstData, String test2) {
this.firstData = firstData;
this.secondData = test2;
}
/**
* Private method, same signature as in Serializable interface
*
* @param stream
* @throws IOException
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
stream.writeObject(secondData);
}
/**
* Private method, same signature as in Serializable interface
*
* @param stream
* @throws IOException
*/
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException {
stream.defaultReadObject();
secondData = (String) stream.readObject();
}
@Override
public String toString() {
return "SerializationTest{" +
"firstData='" + firstData + '\'' +
", secondData='" + secondData + '\'' +
'}';
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileOutputStream fos = null;
ObjectOutputStream oos = null;
try {
fos = new FileOutputStream("object.out");
oos = new ObjectOutputStream(fos);
SerializationTest sTest = new SerializationTest("First Data", "Second data");
oos.writeObject(sTest);
} finally {
oos.close();
fos.close();
}
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream("object.out");
ois = new ObjectInputStream(fis);
SerializationTest sTest = (SerializationTest) ois.readObject();
System.out.println(sTest);
} finally {
ois.close();
fis.close();
}
//Output:
//SerializationTest{firstData='First Data', secondData='Second data'}
}
}
正如你所看到的,也有實現的私有方法writeObject
和readObject
。
的問題是:
爲了什麼的ObjectOutputStream和ObjectInputStream的使用反射來訪問私有方法?
Java中包含了多少這樣的後門?
不是後門,但http://twitteroverflow.com/questions/15496/hidden-features-of-java – OscarRyz 2011-04-15 21:11:07
順便說一句,你的資源處理不正確。標準格式爲:'資源資源=獲取();嘗試{使用(資源); } finally {resource.release(); }'。您應該爲每個資源單獨執行此操作。在Java SE 6中,您可以編寫'try(Resource resource = acquire()){use(resource);在大多數情況下。不需要關閉對象流,除了僅在快樂案例中刷新ObjectOutputStream(也就是說,在「try」的主體中;在finally中的刷新也會在錯誤情況下執行) ,這不是你想要的)。 – 2011-04-15 21:30:55
@Tom:'try(...){'語法已經在Java SE 6中?這對我來說是新的,我認爲這將是隻有7. – 2011-04-15 23:34:12