让你的对象跑出内存,写入到磁盘或者进行网络传输,一文掌握Java对象序列化

简介: 让你的对象跑出内存,写入到磁盘或者进行网络传输,一文掌握Java对象序列化

文章目录


对象序列化是什么

如何让对象可序列化

让对象跑出内存


对象序列化是什么


对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。


序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原。


序列化是 RMI(Remote Method Invoke – 远程方法调用)过程的参数和返回值都必须实现的机制,而 RMI 是 JavaEE 的基础。因此序列化机制是JavaEE 平台的基础。


如果让某个对象支持序列化机制,则必须让对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现Serializable或者Externalizable两个接口之一。否则,会抛出NotSerializableException异常。


凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:


private static final long serialVersionUID;


serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。如果类没有显示定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID可能发生变化。所以建议进行显式声明。


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


如何让对象可序列化


import java.io.Serializable;
/**
 * @Author: Yeman
 * @Date: 2021-09-27-8:27
 * @Description:
 */
class pet implements Serializable { //实现Serializable接口
    public static final long serialVersionUID = 999794470754667999L; //显示赋值全局变量serialVersionUID
    private String name;
    public pet(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "pet{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class Person implements Serializable { //实现Serializable接口
    public static final long serialVersionUID = 6849794470754667999L; //显示赋值全局变量serialVersionUID
    private String name;
    private int age;
    private pet pet;
    public Person(String name, int age, pet pet) {
        this.name = name;
        this.age = age;
        this.pet = pet;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", pet=" + pet +
                '}';
    }
}


让对象跑出内存


通过对象流ObjectInputStream和OjbectOutputSteam。


序列化:用ObjectOutputStream类保存基本类型数据或对象的机制,将内存中的对象写入磁盘或者进行网络传输。


反序列化:用ObjectInputStream类读取基本类型数据或对象的机制,将磁盘或者进行网络传输中的序列化对象读过来。


ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。


流的相关知识可以见《IO流相关知识点》。


序列化(ObjectOutputStream):


import java.io.*;
/**
 * @Author: Yeman
 * @Date: 2021-09-26-20:13
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("IO\\test.txt"));
            oos.writeUTF(new String("你好世界!"));
            oos.flush();
            oos.writeObject(new Person("Lily",20,new pet("Xinxin")));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (oos != null) oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


反序列化(ObjectInputStream):


import java.io.*;
/**
 * @Author: Yeman
 * @Date: 2021-09-26-20:13
 * @Description:
 */
public class Test {
    public static void main(String[] args) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("IO\\test.txt"));
            String s = ois.readUTF();
            Person o = (Person) ois.readObject();
            System.out.println(o.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}



相关文章
|
2月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
341 0
|
3月前
|
安全 Java 应用服务中间件
Spring Boot + Java 21:内存减少 60%,启动速度提高 30% — 零代码
通过调整三个JVM和Spring Boot配置开关,无需重写代码即可显著优化Java应用性能:内存减少60%,启动速度提升30%。适用于所有在JVM上运行API的生产团队,低成本实现高效能。
369 3
|
4月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
2月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
95 4
|
2月前
|
存储 缓存 Java
【深入浅出】揭秘Java内存模型(JMM):并发编程的基石
本文深入解析Java内存模型(JMM),揭示synchronized与volatile的底层原理,剖析主内存与工作内存、可见性、有序性等核心概念,助你理解并发编程三大难题及Happens-Before、内存屏障等解决方案,掌握多线程编程基石。
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
196 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
218 1
|
3月前
|
缓存 监控 Kubernetes
Java虚拟机内存溢出(Java Heap Space)问题处理方案
综上所述, 解决Java Heap Space溢出需从多角度综合施策; 包括但不限于配置调整、代码审查与优化以及系统设计层面改进; 同样也不能忽视运行期监控与预警设置之重要性; 及早发现潜在风险点并采取相应补救手段至关重要.
573 17
|
4月前
|
缓存 安全 Java
Java反射机制:动态操作类与对象
Java反射机制是运行时动态操作类与对象的强大工具,支持获取类信息、动态创建实例、调用方法、访问字段等。它在框架开发、依赖注入、动态代理等方面有广泛应用,但也存在性能开销和安全风险。本文详解反射核心API、实战案例及性能优化策略,助你掌握Java动态编程精髓。
|
4月前
|
存储 监控 算法
Java垃圾回收机制(GC)与内存模型
本文主要讲述JVM的内存模型和基本调优机制。

热门文章

最新文章