让我们说我的班级MyClass
有10个变量。通过使用Serializable
标记类,我们将所有10个变量序列化。
我的问题是,有没有办法只序列化其中的一些变量,让我们说5只?
我知道可以通过将变量标记为transient
来完成。但我想知道是否还有其他方法可以使用transient
关键字。
答案 0 :(得分:3)
如果您的类实现了Externalizable
接口,那么您将更好地控制对象的序列化方式。
请注意,与Serializable
不同,Externalizable
界面不是标记,您需要实施readExternal()
和writeExternal()
方法,实际上< em>以编程方式选择要序列化的类成员以及如何进行反序列化。
更多信息:
答案 1 :(得分:0)
Java支持自定义序列化。请阅读“自定义默认协议”一节。
然而,有一个奇怪但狡猾的解决方案。通过使用内置 序列化机制的特点,开发人员可以增强 通过在其类文件中提供两个方法来实现正常过程。 那些方法是:private void writeObject(ObjectOutputStream out)抛出IOException;
private void readObject(ObjectInputStream in)抛出IOException, ClassNotFoundException的;
答案 2 :(得分:0)
要自定义序列化时的选项是使用序列化代理:而不是您的&#34; real&#34;对象,您创建一个序列化的替代品。序列化框架使用writeReplace()/readResolve()
方法,允许您完成此操作。
这大致如下:
public class Foo implements Serializable {
private final String bar;
private final String baz;
private static class FooProxy implements Serializable {
private final String barBaz;
private FooProxy(Foo foo) {
this.barBaz = foo.bar + "|" + foo.baz; //don't do this for real
}
private Object readResolve() {
String [] arr = this.barBaz.split( "|" );
return new Foo(arr[0], arr[1]);
}
}
private Object writeReplace() {
return new FooProxy(this);
}
// this method is required to stop a maliciously constructed serialized form to be deserialized
private void readObject(ObjectInputStream ois) throws InvalidObjectException {
throw new InvalidObjectException( "Use a proxy." );
}
}
因此,每次Foo
被序列化时,它都会被一个具有完全不同字段的FooProxy
对象替换,并且每次FooProxy
被反序列化时,它都会被替换使用相应的Foo
。
这种技术的优点是你可以完全将序列化形式与内部表示分开,允许你任意改变内部表示,只要它可以从序列化形式重建。