“对象序列化”是什么意思?您能用一些例子解释一下吗?

有帮助吗?

解决方案

序列化是对象物的一系列字节的转换,从而使该对象可容易地保存到持久存储或通过通信链路流。然后将字节流可以被反序列化。 - 转换成原来的对象的副本

其他提示

可以认为串行化的作为对象实例转换成一个字节序列(其可以是二元或不依赖于执行)的处理。

当要从一个JVM跨越网络的一个对象的数据,例如发送到另一这是非常有用的。

在Java中,序列化机制是内置于平台,但你需要实现的序列化的接口,使对象序列化。

您还可以防止您的对象有些数据不被序列化通过标记属性作为的瞬态的。

最后,你可以覆盖默认的机制,并提供自己的;这可能是适合于某些特殊情况下。要做到这一点,您使用的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 但我想这已经太长以将其覆盖。

敢于回答6年前的老问题,为刚接触Java的人增加了非常高水平的理解

什么是序列化?

将对象转换为字节,然后将字节转换回对象(反序列化)。

什么时候使用序列化?

当我们想要持久化对象时。当我们希望对象在 JVM 的生命周期之外继续存在时。

现实世界的例子:

自动提款机:当账户持有人尝试通过 ATM 从服务器提款时,账户持有人信息(如提款详细信息)将被序列化并发送到服务器,在服务器中详细信息被反序列化并用于执行操作。

java中序列化是如何进行的。

  1. 实施 java.io.Serializable 接口(标记接口,因此没有方法可以实现)。

  2. 持久化对象:使用 java.io.ObjectOutputStream 类,一个过滤器流,它是较低级别字节流的包装器(将对象写入文件系统或通过网络线传输扁平对象并在另一端重建)。

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

记住:

当您序列化一个对象时,只会保存该对象的状态,而不是该对象的类文件或方法。

当您序列化 2 字节对象时,您会看到 51 字节序列化文件。

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

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

  • 首先写入序列化流魔术数据(STREAM_MAGIC=“AC ED”且STREAM_VERSION=JVM 版本)。
  • 然后它写出与实例关联的类的元数据(类的长度、类的名称、serialVersionUID)。
  • 然后它递归地写出超类的元数据,直到找到 java.lang.Object.
  • 然后从与实例关联的实际数据开始。
  • 最后将与实例关联的对象的数据从元数据开始写入实际内容。

如果您对有关 Java 序列化的更多信息感兴趣,请查看此 关联.

编辑 :又一个好 关联 读书。

这将回答一些常见问题:

  1. 如何不序列化类中的任何字段。
    答:使用瞬态关键字

  2. 当子类被序列化时,父类也会被序列化吗?
    答:不,如果父级未扩展可序列化接口,则父级字段不会被序列化。

  3. 当父类被序列化时,子类也会被序列化吗?
    答:是的,默认情况下子类也会被序列化。

  4. 如何避免子类被序列化?
    答:A。重写 writeObject 和 readObject 方法并抛出 NotSerializableException.

    b.您还可以将子类中的所有字段标记为瞬态。

  5. 一些系统级类(例如 Thread、OutputStream 及其子类以及 Socket)是不可序列化的。

序列化走的是一条“活”在对象存储器并将其转换为可以某处被存储的格式(例如,在存储器中。在磁盘上)和后来的“反序列化”回一个活对象。

我的两分钱来自我自己的博客:

下面是序列化的详细解释: :(我自己的博客)

序列化:

序列化是持久化对象状态的过程。它以字节序列的形式表示和存储。这可以存储在文件中。从文件中读取对象状态并恢复它的过程称为反序列化。

序列化需要什么?

在现代架构中,总是需要存储对象状态然后检索它。例如,在 Hibernate 中,要存储对象,我们应该使类可序列化。它的作用是,一旦对象状态以字节形式保存,就可以将其传输到另一个系统,然后该系统可以从状态中读取并检索类。对象状态可以来自数据库或不同的 jvm 或来自单独的组件。借助序列化,我们可以检索对象状态。

代码示例及说明:

首先我们看一下Item Class:

public class Item implements Serializable{

    /**
    *  This is the Serializable class
    */
    private static final long serialVersionUID = 475918891428093041L;
    private Long itemId;
    private String itemName;
    private transient Double itemCostPrice;
    public Item(Long itemId, String itemName, Double itemCostPrice) {
        super();
        this.itemId = itemId;
        this.itemName = itemName;
        this.itemCostPrice = itemCostPrice;
      }

      public Long getItemId() {
          return itemId;
      }

     @Override
      public String toString() {
          return "Item [itemId=" + itemId + ", itemName=" + itemName + ", itemCostPrice=" + itemCostPrice + "]";
       }


       public void setItemId(Long itemId) {
           this.itemId = itemId;
       }

       public String getItemName() {
           return itemName;
       }
       public void setItemName(String itemName) {
            this.itemName = itemName;
        }

       public Double getItemCostPrice() {
            return itemCostPrice;
        }

        public void setItemCostPrice(Double itemCostPrice) {
             this.itemCostPrice = itemCostPrice;
        }
}

在上面的代码中可以看出 物品 类工具 可串行化.

这是使类能够序列化的接口。

现在我们可以看到一个名为 序列号版本UID 被初始化为 Long 变量。该数字由编译器根据类的状态和类属性计算得出。当 jvm 从文件中读取对象状态时,该数字将帮助 jvm 识别对象的状态。

为此我们可以看一下Oracle官方文档:

序列化运行时与每个可序列化的类 版本号,称为 serialVersionUID,用于 反序列化以验证序列化的发送方和接收方 对象加载了与 关于序列化。如果接收方已经加载了 对象,该对象具有与 对应的 sender 的类,则反序列化将导致 InvalidClassException。可序列化的类可以声明自己的 serialVersionUID,通过声明一个名为 “serialVersionUID”,必须是静态的、final的,并且类型为 long:ANY-ACCESS-MODIFIER 静态最终长serialVersionUID = 42L;如果 serializable 类不显式声明 serialVersionUID, 则序列化运行时将计算默认值 serialVersionUID 值,该值基于 类,如 Java(TM) 对象序列化中所述 规范。但是,强烈建议所有 可序列化类显式声明 serialVersionUID 值,因为 默认的 serialVersionUID 计算对类高度敏感 详细信息可能因编译器实现而异,并且可以 从而导致意外的 InvalidClassExceptions 反序列化。因此,为了保证一致的 serialVersionUID 跨不同 Java 编译器实现的值,可序列化 类必须声明一个显式的 serialVersionUID 值。它也是 强烈建议显式 serialVersionUID 声明使用 private 修饰符,因为此类声明仅适用于 立即声明的 class--serialVersionUID 字段不是 作为继承的成员有用。

如果您注意到我们使用了另一个关键字,那就是 短暂的.

如果字段不可序列化,则必须将其标记为瞬态。这里我们标记了 商品成本价 作为瞬态并且不希望将其写入文件中

现在让我们看看如何将对象的状态写入文件中,然后从那里读取它。

public class SerializationExample {

    public static void main(String[] args){
        serialize();
       deserialize();
    } 

    public static void serialize(){

         Item item = new Item(1L,"Pen", 12.55);
         System.out.println("Before Serialization" + item);

         FileOutputStream fileOut;
         try {
             fileOut = new FileOutputStream("/tmp/item.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut);
             out.writeObject(item);
             out.close();
             fileOut.close();
             System.out.println("Serialized data is saved in /tmp/item.ser");
           } catch (FileNotFoundException e) {

                  e.printStackTrace();
           } catch (IOException e) {

                  e.printStackTrace();
           }
      }

    public static void deserialize(){
        Item item;

        try {
                FileInputStream fileIn = new FileInputStream("/tmp/item.ser");
                ObjectInputStream in = new ObjectInputStream(fileIn);
                item = (Item) in.readObject();
                System.out.println("Serialized data is read from /tmp/item.ser");
                System.out.println("After Deserialization" + item);
        } catch (FileNotFoundException e) {
                e.printStackTrace();
        } catch (IOException e) {
               e.printStackTrace();
        } catch (ClassNotFoundException e) {
               e.printStackTrace();
        }
     }
}

在上面我们可以看到一个对象的序列化和反序列化的例子。

为此我们使用了两个类。为了序列化对象,我们使用了 ObjectOutputStream。我们使用 writeObject 方法将对象写入文件中。

对于反序列化,我们使用了 ObjectInputStream,它从文件中读取对象。它使用 readObject 从文件中读取对象数据。

上述代码的输出如下:

Before SerializationItem [itemId=1, itemName=Pen, itemCostPrice=12.55]
Serialized data is saved in /tmp/item.ser
After DeserializationItem [itemId=1, itemName=Pen, itemCostPrice=null]

请注意 商品成本价 来自反序列化对象的是 无效的 因为它没有写。

我们已经在本文第一部分讨论了 Java 序列化的基础知识。

现在让我们深入讨论它及其工作原理。

首先让我们从 序列号版本uid。

序列号版本UID 用作可序列化类中的版本控制。

如果您没有显式声明serialVersionUID,JVM 将根据 Serialized 类的各种属性自动为您执行此操作。

Java计算serialversionuid的算法 (在这里阅读更多详细信息)

  1. 班级名称。
    1. 类修饰符写为 32 位整数。
    2. 每个接口的名称按名称排序。
    3. 对于按字段名称排序的类的每个字段(私有静态和私有瞬态字段除外:字段的名称。这 以 32 位整数形式编写的字段的修饰符。描述符 的领域。
    4. 如果存在类初始值设定项,请写出以下内容:方法的名称,.
    5. 该方法的修饰符 java.lang.reflect.Modifier.STATIC,写为 32 位整数。
    6. 该方法的描述符 ()V。
    7. 对于按方法名称和签名排序的每个非私有构造函数:方法的名称,.的修饰符 以 32 位整数形式编写的方法。方法的描述符。
    8. 对于按方法名称和签名排序的每个非私有方法:方法的名称。该方法的修饰符写为32位整数。方法的描述符。
    9. SHA-1 算法在 DataOutputStream 生成的字节流上执行,并生成五个 32 位值 sha[0..4]。这 哈希值由 SHA-1 消息摘要。如果消息摘要的结果,则五个 32 位字 H0 H1 H2 H3 H4 位于五个 int 值的数组中,名为 SHA,哈希值的计算方式如下:
    long hash = ((sha[0] >>> 24) & 0xFF) |
>            ((sha[0] >>> 16) & 0xFF) << 8 |
>            ((sha[0] >>> 8) & 0xFF) << 16 |
>            ((sha[0] >>> 0) & 0xFF) << 24 |
>            ((sha[1] >>> 24) & 0xFF) << 32 |
>            ((sha[1] >>> 16) & 0xFF) << 40 |
>            ((sha[1] >>> 8) & 0xFF) << 48 |
>        ((sha[1] >>> 0) & 0xFF) << 56;

Java的序列化算法

序列化对象的算法描述如下:
1.它写出与实例关联的类的元数据。
2.它递归地写出超类的描述,直到找到 java.lang.object.
3.一旦完成元数据信息的写入,它就会开始处理与实例关联的实际数据。但这一次,它 从最顶层的超类开始。
4.它以递归方式写入与实例关联的数据,从最小的超类开始到最派生的类。

要记住的事情:

  1. 类中的静态字段无法序列化。

    public class A implements Serializable{
         String s;
         static String staticString = "I won't be serializable";
    }
    
  2. 如果读取类中的serialversionuid不同,它将抛出 InvalidClassException 例外。

  3. 如果一个类实现了可序列化,那么它的所有子类也将是可序列化的。

    public class A implements Serializable {....};
    
    public class B extends A{...} //also Serializable
    
  4. 如果一个类引用了另一个类,则所有引用都必须是可序列化的,否则将不会执行序列化过程。在这种情况下, 不可序列化异常 在运行时抛出。

例如:

public class B{
     String s,
     A a; // class A needs to be serializable i.e. it must implement Serializable
}

序列化装置在持久的Java对象。如果要保存该对象的状态和想要稍后重建的状态(可以是另一个JVM)序列可以被使用。

请注意,一个对象的属性,只是要被保存。如果您想再次复活的对象,你应该有类文件,因为成员变量只将被存储,而不是成员函数。

例如:

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

在Searializable是一个标记接口这标志着您的类是可序列化。标记接口意味着它是一个空的接口,并使用该接口将通知此类可制成可序列化的JVM。

序列化是一个对象的状态转换为比特,以便它可以被存储在硬盘驱动器上的过程。当你反序列化的同一个对象,这将在后面保持其状态。它可以重新创建对象,而无需用手工以保存对象的属性。

http://en.wikipedia.org/wiki/Serialization

序列化是在存储介质中保存的对象(诸如文件或存储器缓冲液),或将其在以二进制形式的网络连接发送的过程。序列化对象是JVM独立的,任何JVM可重新序列。在这种情况下,“内存”中的Java对象状态被转换成字节流。这种类型的文件无法被用户理解。它是一种特殊类型的对象,即由JVM(Java虚拟机)重复使用。序列化对象的此过程也称为放气或编组中的对象。

在对象被序列化必须实现java.io.Serializable接口。 为对象默认序列化机制写入对象的类,类签名,和所有非瞬态和非静态字段的值。

class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,

ObjectOutput接口扩展了DataOutput接口,并增加了方法用于序列化的对象和字节写入该文件。该ObjectOutputStream扩展java.io.OutputStream和工具ObjectOutput接口。其序列对象,数组和其它值到流。因此ObjectOutputStream的构造函数写为:

ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));

以上代码已被用来创建一个与ObjectOutput构造它接受ObjectOutputStream( )的实例作为参数的FileOuputStream类的实例。

ObjectOutput接口通过实现ObjectOutputStream类使用。所述ObjectOutputStream构造序列化的对象。

反序列化在Java对象

序列化的相反操作被称为反串行化,即从一系列的字节是S称为反序列化也称为充气或解组提取数据。

ObjectInputStream延伸java.io.InputStream并实现ObjectInput接口。它反序列化对象,数组和其他值从输入流。因此ObjectInputStream的构造函数写为:

ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));

上面的程序的代码创建ObjectInputStream类的实例反序列化该已序列由ObjectInputStream类文件。上面的代码建立使用保持必须被反序列化,因为FileInputStream构造函数需要输入流中的指定的文件对象ObjectInputStream()类的实例的实例。

爪哇 对象序列化

enter image description here

Serialization 是一种将 Java 对象图转换为字节数组进行存储的机制(to disk file)或传输(across a network),然后使用 反序列化 我们可以恢复对象的图。使用引用共享机制正确恢复对象图。 但在存储之前,请检查输入文件/网络中的serialVersionUID和.class文件serialVersionUID是否相同。如果没有,抛出一个 java.io.InvalidClassException.

每个版本化的类必须标识它能够写入流并从中读取的原始类版本。例如,版本化类必须声明:

语法

// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L;
private static final long serialVersionUID = 3487495895819393L;

序列号版本UID 对于序列化过程至关重要。但开发者可以选择将其添加到java源文件中。如果不包含serialVersionUID,则序列化运行时将生成serialVersionUID并将其与类关联。序列化对象将包含此serialVersionUID 以及其他数据。

笔记 - 强烈建议所有可序列化类显式声明一个serialVersionUID, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, ,因此可能会导致反序列化过程中出现意外的serialVersionUID冲突,从而导致反序列化失败。

检查可序列化的类

enter image description here


Java 对象只能序列化。如果一个类或其任何超类实现了 java.io.Serialized 接口 或其子接口, java.io.Externalized.

  • 一个类必须实现 java.io.Serialized接口 为了成功序列化它的对象。Serialized 是一个标记接口,用于通知编译器实现它的类必须添加可序列化行为。 这里Java虚拟机(JVM)负责其自动序列化。

    瞬态关键字: java.io.Serializable interface

    在序列化对象时,如果我们不希望对象的某些数据成员被序列化,我们可以使用瞬态修饰符。瞬态关键字将阻止该数据成员被序列化。

    • 序列化过程会忽略声明为瞬态或静态的字段。

    短暂的 & 易挥发的

    +--------------+--------+-------------------------------------+
    |  Flag Name   |  Value | Interpretation                      |
    +--------------+--------+-------------------------------------+
    | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.|
    +--------------+--------+-------------------------------------+
    |ACC_TRANSIENT | 0x0080 | Declared transient; not written or  |
    |              |        | read by a persistent object manager.|
    +--------------+--------+-------------------------------------+
    
    class Employee implements Serializable {
        private static final long serialVersionUID = 2L;
        static int id;
    
        int eno; 
        String name;
        transient String password; // Using transient keyword means its not going to be Serialized.
    }
    
  • 实现Externalized 接口允许对象完全控制对象序列化形式的内容和格式。调用Externalized接口的方法writeExternal和readExternal来保存和恢复对象状态。当由类实现时,它们可以使用 ObjectOutput 和 ObjectInput 的所有方法写入和读取自己的状态。对象有责任处理发生的任何版本控制。

    class Emp implements Externalizable {
        int eno; 
        String name;
        transient String password; // No use of transient, we need to take care of write and read.
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(eno);
            out.writeUTF(name);
            //out.writeUTF(password);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.eno = in.readInt();
            this.name = in.readUTF();
            //this.password = in.readUTF(); // java.io.EOFException
        }
    }
    
  • 只有支持 java.io.Serialized 或 java.io.Externalizable 接口的对象才可以 written to/read from 溪流。每个可序列化对象的类都经过编码,包括类名和类签名、对象字段和数组的值以及从初始对象引用的任何其他对象的闭包。

文件的可序列化示例

public class SerializationDemo {
    static String fileName = "D:/serializable_file.ser";

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Employee emp = new Employee( );
        Employee.id = 1; // Can not Serialize Class data.
        emp.eno = 77;
        emp.name = "Yash";
        emp.password = "confidential";
        objects_WriteRead(emp, fileName);

        Emp e = new Emp( );
        e.eno = 77;
        e.name = "Yash";
        e.password = "confidential";
        objects_WriteRead_External(e, fileName);

        /*String stubHost = "127.0.0.1";
        Integer anyFreePort = 7777;
        socketRead(anyFreePort); //Thread1
        socketWrite(emp, stubHost, anyFreePort); //Thread2*/

    }
    public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
        FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );
        objectOut.writeObject( obj );
        objectOut.close();
        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            FileInputStream fis = new FileInputStream( new File( serFilename ) );
            ObjectInputStream ois = new ObjectInputStream( fis );
            Object readObject;
            readObject = ois.readObject();
            String calssName = readObject.getClass().getName();
            System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException

            Employee emp = (Employee) readObject;
            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
        FileOutputStream fos = new FileOutputStream(new File( serFilename ));
        ObjectOutputStream objectOut = new ObjectOutputStream( fos );

        obj.writeExternal( objectOut );
        objectOut.flush();

        fos.close();

        System.out.println("Data Stored in to a file");

        try {
            // create a new instance and read the assign the contents from stream.
            Emp emp = new Emp();

            FileInputStream fis = new FileInputStream(new File( serFilename ));
            ObjectInputStream ois = new ObjectInputStream( fis );

            emp.readExternal(ois);

            System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);

            ois.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

通过网络可串行化的示例

分发对象的状态跨越不同的地址空间,或者在同一台计算机上的不同进程中,甚至在通过网络连接的多台计算机中,但它们通过共享数据和调用方法来协同工作。

/**
 * Creates a stream socket and connects it to the specified port number on the named host. 
 */
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
    try { // CLIENT - Stub[marshalling]
        Socket client = new Socket(stubHost, anyFreePort);
        ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
        out.writeObject(objectToSend);
        out.flush();
        client.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
// Creates a server socket, bound to the specified port. 
public static void socketRead(  Integer anyFreePort ) {
    try { // SERVER - Stub[unmarshalling ]
        ServerSocket serverSocket = new ServerSocket( anyFreePort );
        System.out.println("Server serves on port and waiting for a client to communicate");
            /*System.in.read();
            System.in.read();*/

        Socket socket = serverSocket.accept();
        System.out.println("Client request to communicate on port server accepts it.");

        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
        Employee objectReceived = (Employee) in.readObject();
        System.out.println("Server Obj : "+ objectReceived.name );

        socket.close();
        serverSocket.close();
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@看

序列化是与它的保存状态下再次接通的Java对象转换为字节数组,然后返回到对象的过程。可用于如发送通过网络或高速缓存的对象的东西到磁盘各种事情。

阅读来自这篇短文这解释了该方法的编程部分相当好,然后移动到以序列化javadoc的。您可能也有兴趣阅读的此相关的问题

返回文件作为对象: http://www.tutorialspoint.com/java/ java_serialization.htm

        import java.io.*;

        public class SerializeDemo
        {
           public static void main(String [] args)
           {
              Employee e = new Employee();
              e.name = "Reyan Ali";
              e.address = "Phokka Kuan, Ambehta Peer";
              e.SSN = 11122333;
              e.number = 101;

              try
              {
                 FileOutputStream fileOut =
                 new FileOutputStream("/tmp/employee.ser");
                 ObjectOutputStream out = new ObjectOutputStream(fileOut);
                 out.writeObject(e);
                 out.close();
                 fileOut.close();
                 System.out.printf("Serialized data is saved in /tmp/employee.ser");
              }catch(IOException i)
              {
                  i.printStackTrace();
              }
           }
        }

    import java.io.*;
    public class DeserializeDemo
    {
       public static void main(String [] args)
       {
          Employee e = null;
          try
          {
             FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             e = (Employee) in.readObject();
             in.close();
             fileIn.close();
          }catch(IOException i)
          {
             i.printStackTrace();
             return;
          }catch(ClassNotFoundException c)
          {
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
          }
          System.out.println("Deserialized Employee...");
          System.out.println("Name: " + e.name);
          System.out.println("Address: " + e.address);
          System.out.println("SSN: " + e.SSN);
          System.out.println("Number: " + e.number);
        }
    }

|*|序列化类:将对象转换为字节,然后将字节转换回对象(反序列化)。

class NamCls implements Serializable
{
    int NumVar;
    String NamVar;
}

|=> 对象序列化是将对象状态转换为字节流的过程。

  • |-> 当您希望对象在 JVM 的生命周期之外存在时实现。
  • |-> 序列化对象可以存储在数据库中。
  • |-> 可序列化对象无法被人类读取和理解,因此我们可以实现安全性。

|=> 对象反序列化是获取对象状态并将其存储到对象(java.lang.Object)中的过程。

  • |-> 在存储其状态之前,它会检查输入文件/网络中的serialVersionUID 与.class 文件serialVersionUID 是否相同。
    如果没有抛出 java.io.InvalidClassException。

|=> Java 对象只有在其类或其任何超类是可序列化的

  • 实现 java.io.Serialized 接口或
  • 它的子接口 java.io.Externalized。

|=> 类中的静态字段无法序列化。

class NamCls implements Serializable
{
    int NumVar;
    static String NamVar = "I won't be serializable";;
}

|=> 如果您不想序列化类的变量,请使用瞬态关键字

class NamCls implements Serializable
{
    int NumVar;
    transient String NamVar;
}

|=> 如果一个类实现了可序列化,那么它的所有子类也将是可序列化的。

|=> 如果一个类引用了另一个类,则所有引用都必须是可序列化的,否则将不会执行序列化过程。在这种情况下,
NotSerializedException 在运行时抛出。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top