JAVA之实体类Serializable序列化

本文介绍了JAVA中实体类实现Serializable接口进行序列化和反序列化的概念及作用。序列化用于将对象转换为字节流以便存储或传输,反序列化则相反。serialVersionUID用于验证类的不同版本间的兼容性。静态属性和transient修饰的成员不会被序列化。文章通过示例代码演示了序列化过程,并验证了静态属性无法序列化的事实。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

客户端访问了某个能开启会话功能的资源, web服务器就会创建一个与该客户端对应的HttpSession对象,每个HttpSession对象都要站用一定的内存空间。如果在某一时间段内访问站点的用户很多,web服务器内存中就会积累大量的HttpSession对象,消耗大量的服务器内存,即使用户已经离开或者关闭了浏览器,web服务器仍要保留与之对应的HttpSession对象,在他们超时之前,一直占用web服务器内存资源。

web服务器通常将那些暂时不活动但未超时的HttpSession对象转移到文件系统或数据库中保存,服务器要使用他们时再将他们从文件系统或数据库中装载入内存,这种技术称为Session的持久化。

将HttpSession对象保存到文件系统或数据库中,需要采用序列化的方式将HttpSession对象中的每个属性对象保存到文件系统或数据库中;将HttpSession对象从文件系统或数据库中装载如内存时,需要采用反序列化的方式,恢复HttpSession对象中的每个属性对象。所以存储在HttpSession对象中的每个属性对象必须实现Serializable接口。

序列化和反序列化的概念

序列化:将Java对象转换为字节流(可以存储或者传输)的过程称为对象的序列化。在序列化期间,对象将其当前状态写入到临时或者持久性存储区。
反序列化:将字节流恢复成Java对象的过程称为对象的反序列化。

序列化的实现:类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。实现Serializable接口是为了告诉jvm这个类的对象可以被序列化。
注意事项:
1.某个类可序列化,则其继承该类的子类也可以被序列化。
2.声明为static的成员变量或者transient修饰的属性,不能被系列化。static变量是类级别的属性,transient修饰的是临时变量。(下面会进行测试)

什么情况化需要系列化

1.将对象存储在硬盘上。
2.将对象通过网络传输。
3.通过RMI远程调用等方式传输对象的时候

serialVersionUID 的作用

serialVersionUID 用来表明类的不同版本间的兼容性

Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。

当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID。不过,强烈建议 所有可序列化类都显式声明 serialVersionUID 值,原因是计算默认的 serialVersionUID 对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的 InvalidClassException。

实现序列化

序列化,就是为了在不同时间或不同平台的JVM之间共享实例对象
序列化对象,代码如下:

package com.lf;

import java.io.Serializable;

public class Demo implements Serializable {
   // private static final long serialVersionUID = 1L;

    private static String NUM = "11";
    private String name;
    transient private String age;

    public static String getNUM() {
        return NUM;
    }
    public static void setNUM(String NUM) {
        Demo.NUM = NUM;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String car) {
        this.age = car;
    }

    @Override
    public String toString() {
        return "Demo{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", NUM='" + NUM + '\'' +
                '}';
    }
}

测试代码如下:

package com.lf;

import java.io.*;

public class Test {

    /**
     * 序列化
     * @throws IOException
     */
    private static void serializableDemo() throws IOException{
        Demo demo = new Demo();
        demo.setName("alien");
        demo.setAge("15");

        //ObjectOutputStream 对象输出流,对demo对象进行序列化,存储到demo.txt中
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\demo.txt")));
        oos.writeObject(demo);
        System.out.println("demo序列化成功");
        oos.close();
    }

    /**
     * 反序列化
     * @return
     * @throws Exception
     */
    private static Demo deserializableDemo() throws Exception{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\demo.txt")));
        Demo person = (Demo) ois.readObject();
        System.out.println("demo反序列化成功");
        return person;
    }


    public static void main(String[] args) throws Exception{
        //序列化
        serializableDemo();
        //反序列化
        Demo demo = deserializableDemo();

        //打印,验证
        System.out.println(demo.toString());

    }

}

运行结果,生成demo.txt文件:
在这里插入图片描述
在这里插入图片描述
从运行的结果上看:
1.成功实现了对象的序列化和反序列化。age属性的值为null,说明了transient修改的属性,是不会被序列化的。
2.静态变量NUM这个得另外测。

验证静态属性能否序列化

1.首先先把Java对象序列化到文件。这个对象中的静态(static)变量的属性值为11.运行结果如下,序列化成功:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.接下来再把Java对象中的静态(static)变量的属性值更改为22,然后对刚才的文件进行反序列化。
在这里插入图片描述
运行结果如下:
在这里插入图片描述
结果分析:刚才序列化的静态变量属性值是11,就是说反序列化出来是11,而结果是22,所以得出结论,静态static的属性,不能序列化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值