19

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

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

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

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

4

3 回答 3

9

在选择接下来要调用哪个类/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

于 2012-05-04T06:45:23.003 回答
2

在试验和浏览序列化机制的代码时发现了一些东西:

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

2)Externalizable写入的数据量比readObject/writeObject的Serializable略少(我在写B的对象时发现以下代码有1个字节的差异)。

对于外部化:

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");
    }       
}

对于可序列化:

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");
    }       
}
于 2012-05-04T08:36:48.683 回答
1

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

于 2015-04-13T15:29:21.523 回答