Java serialization of transient fields
I am reading Thinking in Java 4th Edition.
There described a strange workaround for serialization of transient
fields:
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'}
}
}
As you can see, there are implemented private methods writeObject
and readObject
.
The questions are:
For what ObjectOutputStream and ObjectInputStream are using Reflection for accessing private methods ?
How many back doors like this are included in the Java ?
Backdoor? It's always been in the spec. It is the only way to implement non-default serialization of an object.
Non-default serialization puts you in the serialization driver's seat. You can write whatever to the output stream and as long as you can read it back and construct your object on the other end of the stream, you'll be ok.
The fact that this person decided to serialize transient fields is just not the issue, the point is that you can do whatever you want if you are implementing your own serialization scheme.
Erm, it isn't a "backdoor" ... you implemented a custom serialization that output the transient fields to the output stream after calling the default serialization which ignored them.
The Serializable interface is marker interface. So its like a tag to explain the java compiler. There are other marker interfaces like Clonable, etc. See here for more. However now a days @annotations are used more.
精彩评论