“对象序列化”是什么意思?你能举例解释一下吗?


当前回答

我喜欢@OscarRyz的礼物方式。虽然在这里我是在继续这个最初由@amitgupta写的连载故事。

即使知道机器人的类结构和序列化的数据,地球的科学家也不能反序列化的数据,可以使机器人工作。

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

火星的科学家们正在等待全额付款。一旦付款完成,火星的科学家与地球的科学家分享了序列号。地球科学家把它设置成机器人级别,一切都好了。

其他回答

您可以将序列化看作是将对象实例转换为字节序列的过程(根据实现的不同,字节序列可能是二进制的,也可能不是)。

当您希望通过网络传输一个对象数据时(例如从一个JVM传输到另一个JVM),它非常有用。

在Java中,序列化机制内置于平台中,但您需要实现Serializable接口以使对象可序列化。

还可以通过将属性标记为transient来防止对象中的某些数据被序列化。

最后,您可以覆盖默认机制,并提供您自己的;这可能适用于某些特殊情况。为此,您需要使用java中的一个隐藏特性。

重要的是要注意,被序列化的是对象的“值”或内容,而不是类定义。因此方法不是序列化的。

下面是一个非常基本的示例,带有注释,以方便阅读:

import java.io.*;
import java.util.*;

// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {

    // These attributes conform the "value" of the object.

    // These two will be serialized;
    private String aString = "The value of that string";
    private int    someInteger = 0;

    // But this won't since it is marked as transient.
    private transient List<File> unInterestingLongLongList;

    // Main method to test.
    public static void main( String [] args ) throws IOException  { 

        // Create a sample object, that contains the default values.
        SerializationSample instance = new SerializationSample();

        // The "ObjectOutputStream" class has the default 
        // definition to serialize an object.
        ObjectOutputStream oos = new ObjectOutputStream( 
                               // By using "FileOutputStream" we will 
                               // Write it to a File in the file system
                               // It could have been a Socket to another 
                               // machine, a database, an in memory array, etc.
                               new FileOutputStream(new File("o.ser")));

        // do the magic  
        oos.writeObject( instance );
        // close the writing.
        oos.close();
    }
}

当我们运行这个程序时,文件“o.ser”被创建,我们可以看到后面发生了什么。

如果我们将:someInteger的值更改为,例如Integer。MAX_VALUE,我们可以比较输出,看看有什么不同。

下面的截图正好显示了这种差异:

你能看出区别吗?;)

在Java序列化中还有一个额外的相关字段:serialversionUID,但我想这已经太长了,无法涵盖它。

我将提供一个类比,以潜在地帮助巩固对象序列化/反序列化的概念目的/实用性。

I imagine object serialization/deserialization in the context of attempting to move an object through a storm drain. The object is essentially "decomposed" or serialized into more modular versions of itself - in this case, a series of bytes - in order to effectively be granted passage through a medium. In a computational sense, we could view the path traveled by the bytes through the storm drain as being akin to bytes traveling through a network. We're transmuting our object in order to conform to a more desirable mode of transportation, or format. The serialized object will typically be stored in a binary file which may later be read from, written to, or both.

也许一旦我们的对象能够作为分解的字节序列通过drain,我们可能希望将对象的表示形式作为二进制数据存储在数据库或硬盘驱动器中。不过,主要的要点是,通过序列化/反序列化,我们可以选择让对象在序列化后保持二进制形式,或者通过执行反序列化来“检索”对象的原始形式。

敢于回答这个6年前的问题,为Java新手增加了非常高级的理解

什么是序列化?

将对象转换为字节

什么是反序列化?

将字节转换回对象(反序列化)。

什么时候使用序列化?

当我们想持久化对象时。 当我们希望对象在JVM生命周期之后仍然存在时。

现实世界的例子:

ATM:当账户持有人试图通过ATM从服务器取款时,提现明细等账户持有人信息将被序列化并发送到服务器,服务器将这些明细反序列化并用于操作。

在java中如何执行序列化。

实现java.io.Serializable接口(标记接口,所以没有方法实现)。 持久化对象:使用java.io.ObjectOutputStream类,这是一个过滤器流,它是底层字节流的包装器(将object写入文件系统或通过网络传输扁平对象并在另一端重新构建)。

writeObject(<<instance>>) -写入一个对象 readObject()——读取一个序列化的对象

记住:

序列化对象时,只保存对象的状态,不保存对象的类文件或方法。

当你序列化一个2字节的对象时,你会看到51字节的序列化文件。

步骤如何序列化和反序列化对象。

答案:它如何转换为51字节的文件?

First writes the serialization stream magic data (STREAM_MAGIC= "AC ED" and STREAM_VERSION=version of the JVM). Then it writes out the metadata of the class associated with an instance (length of the class, the name of the class, serialVersionUID). Then it recursively writes out the metadata of the superclass until it finds java.lang.Object. Then starts with the actual data associated with the instance. Finally writes the data of objects associated with the instance starting from metadata to the actual content.

你也可以在这里查看我的Youtube视频解释

编辑:阅读的参考链接。

这将回答一些常见的问题:

How not to serialize any field in the class. Ans: use transient keyword When child class is serialized does parent class get serialized? Ans: No, If a parent is not extending the Serializable interface parents field don't get serialized. When a parent is serialized does child class get serialized? Ans: Yes, by default child class also gets serialized. How to avoid child class from getting serialized? Ans: a. Override writeObject and readObject method and throw NotSerializableException. b. also you can mark all fields transient in child class. Some system-level classes such as Thread, OutputStream, and its subclasses, and Socket are not serializable.

序列化意味着在java中持久化对象。如果您希望保存对象的状态,并希望稍后重新构建该状态(可能在另一个JVM中),则可以使用序列化。

注意,对象的属性只会被保存。如果你想再次恢复对象,你应该有类文件,因为只存储成员变量而不存储成员函数。

eg:

ObjectInputStream oos = new ObjectInputStream(                                 
                                 new FileInputStream(  new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();

serializable是一个标记接口,用来标记你的类是可序列化的。标记接口意味着它只是一个空接口,使用该接口将通知JVM该类可以被序列化。

我喜欢@OscarRyz的礼物方式。虽然在这里我是在继续这个最初由@amitgupta写的连载故事。

即使知道机器人的类结构和序列化的数据,地球的科学家也不能反序列化的数据,可以使机器人工作。

Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:

火星的科学家们正在等待全额付款。一旦付款完成,火星的科学家与地球的科学家分享了序列号。地球科学家把它设置成机器人级别,一切都好了。