Java:writeObject与writeExternal的效率

时间:2012-05-04 06:41:05

标签: java serialization

据说Java的默认序列化机制效率不高,因为a)它发现通过反射写入/读取的字段通常很慢b)它将额外的数据写入流中。

提高效率的一种方法是实现Externalizable及其writeExternal / readExternal方法。

这里有一个问题:如果我改为提供'writeObject / readObject'方法并且不在其中调用deafiltWriteObject / defaultReadObject,那么这个机制将不会使用反射来确定要写入/读取的字段,加上它赢了“ t将额外的数据写入流(或者它会不确定)。那么从效率的角度来看,实现上面提到的writeObject / readObject与实现Externalizable一样吗?或者后一种选择是否会带来一些前者不具备的实际效益?

编辑:当然,差异在于实现readObject / writeObject的Serializable类是子类化的,并且如果子类有自己的readObject / writeObject,则它们不需要调用super的readObject / writeObject。如果超级/子类改为实现Externalizable,则不是这样。在这种情况下,需要显式调用super的writeExternal / readExternal。 但是,从效率的角度来看,这种差异是无关紧要的。

3 个答案:

答案 0 :(得分:8)

在选择下一个要调用的class / writeObject / readObject时,仍有一些问题。但它显着减少了。

这可以与Externalizable执行相同的操作,具体取决于您正在执行的操作以及是否使用它为您提供的额外选项。例如readObject假定您每次都创建一个新对象,Externalizable具有readResolve,这意味着您可以重用对象。

http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/input.html

在许多情况下,回收对象是加速反序列化的“下一步”。 (假设这是你的选择)

http://vanillajava.blogspot.co.uk/2011/10/recycling-objects-to-improve.html

答案 1 :(得分:1)

在尝试和完成序列化机制的代码时发现了一些事情:

1)如果发现对象是Externalizable,则将其强制转换为Externalizable,并在其上调用相应的方法;而对于Serializable对象,反射性地检查它是否具有readObject / writeObject。所以也许这会让它稍慢,

2)为Externalizable写入的数据量比使用readObject / writeObject的Serializable少一点(当我写B的对象时,我发现以下代码的差异为1个字节。)

对于Externalizable:

static class A implements Externalizable
{
    @Override
    public void writeExternal(ObjectOutput out) throws IOException 
    {
        System.out.println("A write called");
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 
    {
        System.out.println("A read called");
    }       
}

static class B extends A implements Externalizable
{       
    @Override
    public void writeExternal(ObjectOutput out) throws IOException 
    {
        super.writeExternal(out);
        System.out.println("B write called");
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException 
    {
        super.readExternal(in);
        System.out.println("B read called");
    }       
}

对于Serializable:

static class A implements Serializable
{
    private void writeObject(ObjectOutputStream out) throws IOException 
    {
        System.out.println("A write called");
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException 
    {
        System.out.println("A read called");
    }       
}

static class B extends A implements Serializable
{       
    private void writeObject(ObjectOutputStream out) throws IOException 
    {           
        System.out.println("B write called");
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException 
    {           
        System.out.println("B read called");
    }       
}

答案 2 :(得分:1)

在类设计方面,主要区别在于Serializable适用于任何类,而Externalizable仅适用于具有公共默认(无参数)构造函数的可变类。