Java 序列化和反序列化的区别在于将内部文件写入文件,然后读取它们并将它们传递给构造函数

Java 序列化和反序列化的区别在于将内部文件写入文件,然后读取它们并将它们传递给构造函数,java,serialization,Java,Serialization,假设我们有一节课 Class A implements serializable{ String s; int i; Date d; public A(){ } public A(String s, int i, Date d){ this.s =s; blah blah } } 现在让我们假设一种方法,我将s,i,d的所有内部值存储到一个文件中,并再次读取它们,然后将它们传递给构造函数并创建一个新对象

假设我们有一节课

Class A implements serializable{

    String s;
    int i;
    Date d;

    public A(){
    }

    public A(String s, int i, Date d){
        this.s =s;
       blah blah
    }
}
现在让我们假设一种方法,我将s,i,d的所有内部值存储到一个文件中,并再次读取它们,然后将它们传递给构造函数并创建一个新对象。其次,我序列化然后反序列化到一个新对象。这两种方法的基本区别是什么

我知道序列化将是缓慢和安全的,而另一种方法则不然。任何其他差异。

在第一种方法中,您负责维护数据值之间的逻辑关系,即存储数据,然后将其读回并构造回对象


在第二种方法中,Java在幕后为您完成了这项工作。

除了实现自定义序列化方案之外,没有什么真正的区别,因此这通常会涉及更多的代码,因为默认情况下,序列化只需要一个接口声明


您可以通过Externalizable实现非常类似的功能—您完全可以控制要保存的数据,因此您可以选择只保存构造函数参数并从中构造对象。通过将非构造函数参数标记为瞬态,您也可以通过序列化实现这一点。

阅读本文,很好地解释了Java RMI的序列化功能,但序列化的解释和问题是相同的:

我看到的主要区别是:

正如其他答案所说,您负责序列化-反序列化。当其中一个属性是另一个大型复杂类时会发生什么?那你打算怎么办?还可以保存它的价值吗? 序列化依赖于反射,而文件依赖于getter/setter/constructor。使用反射,您不需要公共setter/getter或带有参数的构造函数。有了文件你就需要它们了。 摘自上述链接:

使用序列化 序列化是内置于核心Java库中的一种机制,用于将对象图写入数据流。然后可以通过编程方式操纵该数据流,并通过反转该过程创建对象的深度副本。这种反转通常称为反序列化

具体而言,序列化有三种主要用途:

作为一种持久性机制。如果使用的流是FileOutputStream,那么数据将自动写入文件。 作为一种复制机制。如果使用的流是ByteArrayOutputStream,则数据将写入内存中的字节数组。然后可以使用此字节数组创建原始对象的副本。 作为一种沟通机制。如果正在使用的流来自一个套接字,那么数据将通过电线自动发送到接收套接字,此时另一个程序将决定要做什么。 需要注意的重要一点是,序列化的使用独立于序列化算法本身。如果我们有一个可序列化的类,我们可以将它保存到一个文件中,或者只需更改使用序列化机制输出的方式,就可以复制它。

Java中的序列化和反序列化

序列化是一个将对象状态存储到任何存储介质中的过程。我们可以将对象的状态存储到文件、数据库表等中。反序列化是从存储介质检索对象的与序列化相反的过程


假设您有一个JavaBean对象,它的变量有一些值。现在,您希望将此对象存储到文件或数据库表中。这可以通过使用序列化来实现。现在,您可以在需要时随时从文件或数据库中再次检索此对象。这可以通过Bobin Goswami的反序列化:Post实现。

Joshua Bloch的《有效Java》第二版中关于序列化的部分在这一主题上读得非常好。要记住一件非常重要的事情:

使用您自己开发的持久性方法是语言内的。从存储区读回数据时,可以控制对象状态的恢复方式。这通常是针对构造函数和/或静态工厂的。对象状态的不变量被保留。保持封装是因为您不一定需要将实现细节作为自定义存储的一部分公开。当然,不利的一面是数据经常需要转移到其他地方,@pakore很好地概括了序列化非常有用的情况

序列化是一种语言外机制。Bloch对为什么要特别小心地调用Serializable接口,特别是Serializable接口,提出了令人信服的论点。序列化可以绕过构造函数,因为对象的重构不依赖于构造函数。有着深远的安全隐患 恩斯。对象状态的不变量易受攻击。此外,使用Serializable往往会使您无法支持特定的类实现,也就是说,它会破坏封装,因为一旦对象可序列化,对象的大部分状态就会成为类导出API的一部分。这可以通过将某些实例字段标记为瞬态来主动推迟


TL;DR:序列化是现代基于Java的计算的一个常见甚至基本方面。如今,数据必须转移,序列化提供了一种常用的通信机制。由于序列化可能会调用漏洞,并且可能会将对象的大部分或全部内部状态作为其导出API的一部分,因此使用可序列化接口时应格外小心。

欢迎使用StackOverflow!发布问题时,请阅读格式帮助。问题区域右侧也会显示信息摘要。您应该能够使用问题下的编辑链接修复格式设置。