瞬态字段的Java序列化
我正在阅读《Java第四版思考》。 这里描述了一种奇怪的瞬态字段的Java序列化,java,serialization,reflection,Java,Serialization,Reflection,我正在阅读《Java第四版思考》。 这里描述了一种奇怪的瞬态字段序列化方法: import java.io.*; public class SerializationTest implements Serializable { private String firstData; //transient field, shouldn't be serialized. transient private String secondData; public Seri
瞬态
字段序列化方法:
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中包含了多少这样的后门?呃,它不是“后门”。。。您实现了一个自定义序列化,在调用忽略临时字段的默认序列化后,将临时字段输出到输出流 呃,这不是“后门”。。。您实现了一个自定义序列化,在调用忽略临时字段的默认序列化后,将临时字段输出到输出流 后门?它一直在规范中。这是实现对象非默认序列化的唯一方法 非默认序列化使您处于序列化驱动程序的位置。您可以将任何内容写入输出流,只要能够读回并在流的另一端构造对象,就可以了
此人决定序列化瞬态字段这一事实并不是问题所在,关键是如果您正在实现自己的序列化方案,您可以做任何您想做的事情。后门?它一直在规范中。这是实现对象非默认序列化的唯一方法 非默认序列化使您处于序列化驱动程序的位置。您可以将任何内容写入输出流,只要能够读回并在流的另一端构造对象,就可以了
此人决定序列化临时字段这一事实并不是问题所在,关键是如果您正在实现自己的序列化方案,您可以做任何您想做的事情。可序列化接口是标记接口。所以它就像一个标签来解释java编译器。还有其他标记接口,如Clonable等。有关更多信息,请参阅。
但是现在使用的更多的是days@annotations。可序列化的接口是marker接口。所以它就像一个标签来解释java编译器。还有其他标记接口,如Clonable等。有关更多信息,请参阅。
然而,现在a days@annotations的使用越来越多。不是后门,而是顺便说一句,您的资源处理没有正确完成。标准形式是:
Resource=acquire();尝试{use(resource);}最后{resource.release();}
。您应该为每个资源单独执行此操作。在JavaSE6中,在大多数情况下,您可以编写try(Resource=acquire()){use(Resource);}
。无需关闭对象流,只需在愉快的情况下刷新ObjectOutputStream
(也就是说在try
的主体中;在最后
中刷新也会在错误情况下完成,这不是您真正想要的)。@Tom{语法已经在JavaSE6中了?这对我来说是新的,我以为它只有7个。@Paŭlo Ebermann Typo.应该是“在JavaSE7中”。(而且您不应该使用-target 1.6-source 1.7
。除了目标必须至少与源代码一样最新的规则外,还需要额外的库支持。可能Retroweaver或类似工具会破解一些东西。)不是后门,但顺便说一句,您的资源处理没有正确完成。标准形式是:resource-resource=acquire();try{use(resource);}最后{resource.release();}
。您应该为每个资源单独执行此操作。在Java SE 6中,您可以编写try(resource-resource=acquire()){use(resource);}
在大多数情况下。无需关闭对象流,只需在愉快的情况下刷新ObjectOutputStream
(也就是说在try
的主体中;最后在中刷新也会在错误情况下关闭对象流,这不是您真正想要的)。@Tom:thetry(…){
语法已经在JavaSE6中了?这对我来说是新的,我以为它只有7个。@Paŭlo Ebermann Typo.应该是“在JavaSE7中”。(而且您不应该使用-target 1.6-source 1.7
。除了目标必须至少与源代码一样最新的规则外,还需要额外的库支持。可能Retroweaver或类似工具会破解一些东西。)