当前位置: 首页 > 知识库问答 >
问题:

Java:writeObject与writeExternal的效率

子车勇锐
2023-03-14

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

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

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

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

共有3个答案

魏安宁
2023-03-14

就类设计而言,主要区别在于Seriezable可以在任何类上工作,而Exextezable仅适用于具有公共默认(no-arg)构造函数的可变类。

陶高扬
2023-03-14

在试验和研究序列化机制的代码时,我发现了一些事情:

1)如果发现对象是可外部化的,则将其转换为外部化,并对其调用相应的方法;而对于可序列化对象,它被反射性地检查它是否具有 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");
    }       
}
仲元凯
2023-03-14

在选择下一个调用哪个类/writeObject/readObject时,仍有一些困难。但其显著降低。

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

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

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

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

 类似资料:
  • 问题内容: 我有一个可能包含数千个对象的模型。我想知道什么是最有效的方式来存储它们并在获得ID后检索单个对象。ID是长数字。 这些是我正在考虑的两个选项。在选项一中,它是一个带有递增索引的简单数组。在选项2中,如果有区别,它是一个关联数组,也可能是一个对象。我的问题是,当我主要需要检索单个对象时,有时又遍历它们并进行排序时,哪一个效率更高。 具有非关联数组的选项一: 选项2与关联数组: 更新: 好

  • 问题内容: 有什么方法可以获取文档中所有对象的集合? 对于Elements来说效果很好,但是s不是Elements。 更新: 我意识到这可以通过遍历DOM来完成-如以下建议所示。我知道如何编写一个DOM- walker函数来查看文档中的每个节点。我希望有某种浏览器本机的方法可以做到这一点。毕竟,我可以通过一个内置调用获得所有s,但不是全部s 有点奇怪。 问题答案: 更新 : 我已经概述了这6种方法

  • spring支持两种不同的验证方法:spring验证和JSR-303 bean验证。这两种方法都可以通过定义一个spring验证器来使用,该验证器委托给包括bean验证器在内的其他委托器。到目前为止还不错。 但当对方法进行注释以实际请求验证时,情况就另当别论了。我可以这样批注 或者像这样 这里,@valid是javax.validation.validated,@validated是org.spr

  • 问题内容: 在C#中寻找与此方法相同的方法 问题答案: 在C#中超级简单:

  • 问题内容: 基本上,我希望每10毫秒调用一次函数。 如何在Java中实现? 问题答案: 您可能想看看Timer。

  • 问题内容: 我想拥有一个与PostgreSQL等效的Sql Server 我可以在SQL Server中执行以下操作: 但是,在有许多列并且查询是临时查询的情况下,这样做非常繁琐。有一个简单的方法吗? 问题答案: 您可以尝试,但它可能会影响您的性能。