84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
温故而知新,可以为师矣。 博客:www.ouyangke.com
一个对象序列化时,按照Java默认的序列化规则,对象内的所有成员都要序列化,也就是说,这些Class都必须实现Serializable。
所以,你有两种改法,一是Address实现Serializable接口,二是对Person中的address成员加上transient标记,这样该成员就不会被序列化进去。
transient
如果 address 成员需要进行序列化的话,则Address类也需要实现Serializable接口。如果 address 成员不需要进行序列化的话,可以加上transient关键字,则address成员不做序列化操作,值为null。如下:
public class Person implements Serializable { private static final long serialVersionUID = 1905122041950251207L; private String name; private transient Address address; // Noncompliant; Address isn't serializable }
当然还有其他方式:比如实现Externalizable接口,重写readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法。还有一个替代实现Externalizable接口方法,还是实现Serializable接口,添加writeObject(ObjectOutputStream obs)和readObject(ObjectInputStream ois)方法。
再说说为什么Address一定要实现Serializable,或者加上transient关键字Person才能进行序列化?先看看不做处理,使用 ObjectOutputStream 来持久化对象,抛出的异常
Exception in thread "main" java.io.NotSerializableException
看ObjectOutputStream源码:
/** * Underlying writeObject/writeUnshared implementation. */ private void writeObject0(Object obj, boolean unshared) throws IOException { //...... // remaining cases if (obj instanceof String) { writeString((String) obj, unshared); } else if (cl.isArray()) { writeArray(obj, desc, unshared); } else if (obj instanceof Enum) { writeEnum((Enum<?>) obj, desc, unshared); } else if (obj instanceof Serializable) { writeOrdinaryObject(obj, desc, unshared); } else { if (extendedDebugInfo) { throw new NotSerializableException( cl.getName() + "\n" + debugInfoStack.toString()); } else { throw new NotSerializableException(cl.getName()); } } } finally { depth--; bout.setBlockDataMode(oldMode); } }
从此可知, 如果被写对象类型是String、Array、Enum、Serializable,就可以进行序列化,否则将抛出NotSerializableException。且在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其它对象也进行序列化。
一个对象序列化时,按照Java默认的序列化规则,对象内的所有成员都要序列化,也就是说,这些Class都必须实现Serializable。
所以,你有两种改法,一是Address实现Serializable接口,二是对Person中的address成员加上
transient
标记,这样该成员就不会被序列化进去。如果 address 成员需要进行序列化的话,则Address类也需要实现Serializable接口。
如果 address 成员不需要进行序列化的话,可以加上transient关键字,则address成员不做序列化操作,值为null。如下:
当然还有其他方式:
比如实现Externalizable接口,重写readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法。
还有一个替代实现Externalizable接口方法,还是实现Serializable接口,添加writeObject(ObjectOutputStream obs)和readObject(ObjectInputStream ois)方法。
再说说为什么Address一定要实现Serializable,或者加上transient关键字Person才能进行序列化?
先看看不做处理,使用 ObjectOutputStream 来持久化对象,抛出的异常
看ObjectOutputStream源码:
从此可知, 如果被写对象类型是String、Array、Enum、Serializable,就可以进行序列化,否则将抛出NotSerializableException。且在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其它对象也进行序列化。