序列化对象可以自定义序列化,也可以使用默认序列化
如何选择呢?
这就要从序列化的目的说起,序列化的目的简单来说就是保存,之后可以还原,这就是说只要我们能达到这个目的,都是ok的。如果都ok那么就可以选择更ok的形式。
看下面这个例子:
OddNum 这是一个极其没有道理的例子,只是为了说明问题
public class OddNum implements Serializable
{
/**
*
*/
private transient static final long serialVersionUID = 9030591748255175591L;
//默认序列化对static成员不进行序列化
//默认序列化对transient修饰的对象不进行序列化,反序列化时给默认值,对于这里的Integer来说就是null
private transient Integer[] is = new Integer[100];
public OddNum()
{
for(int i=0;i<is.length;i++)
{
is[i] = i*2+1;
}
}
private void writeObject(ObjectOutputStream out) throws IOException
{
out.defaultWriteObject();
out.writeInt(is.length);
System.out.println("");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
in.defaultReadObject();
int capacity = in.readInt();
is = new Integer[capacity];
for(int i=0;i<capacity;i++)
{
is[i] = i*2+1;
}
}
public Integer[] getIs() {
return is;
}
}
使用默认序列化是ok的。
因为Integer[]的值仅仅与length有关,只要拿到length我们就可以还原原始的对象,所以选择仅仅序列化length也是可以达到目的,所以选择自定义序列化也是ok的。
现在就再这两种方式中哪一种比较好呢,你会选择将整个数组序列化,还是仅仅序列化一个int值,很显然选择自定义序列化只序列化length是更好的选择。
测试程序
@Test
public void testOut00() throws FileNotFoundException, IOException
{
OddNum o = new OddNum();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("D:\\temp00.txt"));
out.writeObject(o);
out.flush();
out.close();
}
@Test
public void testIn00() throws FileNotFoundException, IOException, ClassNotFoundException
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:\\temp00.txt"));
OddNum o = (OddNum)in.readObject();
in.close();
Integer[] is = o.getIs();
for(Integer temp : is)
{
System.out.print(temp+" ");
}
}
解释一下readObject:
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
in.defaultReadObject();
int capacity = in.readInt();
is = new Integer[capacity];
for(int i=0;i<capacity;i++)
{
is[i] = i*2+1;
}
}
反序列化其实是重新构造了一个新的实例,可以将反序列化看做是一个以流为参数的构造函数。
这里的is就是反序列化时,生成的新的对象的成员。由于is被transient 修饰,in.defaultReadObject()执行完以后,它的值是null,所以这里需要is = new Integer[capacity]
初始化一下,然后通过拿到的length赋值。这样就还原了序列化之前的对象。
从过去几个测试程序可以看出,序列化无论怎么实现,用法是完全一样的,之后就不再写测试程序了。