首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java: writeObject与writeExternal的效率

Java: writeObject与writeExternal的效率
EN

Stack Overflow用户
提问于 2012-05-04 06:41:04
回答 3查看 6.9K关注 0票数 19

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

使其更有效的一种方法是实现Externalizable及其写外部/readExternal方法。

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

编辑:当然,区别在于实现readObject/writeObject的可序列化类被子类化,如果子类有自己的readObject/writeObject,则不需要调用Super‘writeObject/writeObject。如果超类/子类相反地实现了Externalizable,则不是这样。在这种情况下,需要显式地调用超级程序的writeExternal/readExternal。然而,从效率的角度来看,这种差异是无关紧要的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-05-04 06:45:23

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

票数 9
EN

Stack Overflow用户

发布于 2012-05-04 08:36:48

在实验和遍历序列化机制的代码时,发现了一些东西:

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

2)为Externalizable编写的数据量略小于readObject/writeObject可序列化的数据量(我在编写B对象时发现以下代码的差异为1字节)。

对于Externalizable:

代码语言:javascript
复制
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");
    }       
}

可序列化:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-04-13 15:29:21

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10443951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档