Java序列化和反序列化示例介绍

以前用序列化都是一些方法需要才实现的,后来业务需求要深拷贝才去研究。参阅了别人博客得出一些总结。

序列化是为了把Java对象转化为字节序列(字节流)的过程。然后深拷贝是通过对流的操作来实现的,序列化后数据方便存储传输。反序列化则是把字节序列反序列化为Java对象

存储方便:因为对象会被回收,序列化后可以持续化存储在磁盘中
传输方便:字节序列(二进制形式)可以进行网络传输和传播。

最好设置一个SerialversionUID,因为序列化和反序列化是对比SerialversionUID来进行的,虽然不设置接口也会默认生成一个,但是要知道序列化对象过程一般都是对象->序列化->存储或传输->反序列化。
举个例子:
先创建一个实体类Student

import lombok.Data;

import java.io.Serializable;

@Data
public class Student implements Serializable {
    private Integer id;
    private String name;
    private String sex;
}
然后创建一个测试类SerializableTest
import serialization.entity.Student;

import java.io.*;

public class SerializableTest {
    public static void main(String[] args) throws Exception {
        serializeStudent();
        Student student = deserializeStudent();
        System.out.println("name:" + student.getName());
        System.out.println("sex:" + student.getSex());
    }

    private static void serializeStudent() throws IOException {
        Student student = new Student();
        student.setId(1);
        student.setName("张三");
        student.setSex("male");

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
                new File("F:/student.txt")));
        out.writeObject(student);
        System.out.println("序列化成功");
        out.close();
    }

    private static Student deserializeStudent() throws Exception {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("F:/student.txt")));
        Student student = (Student) in.readObject();
        System.out.println("反序列化成功");
        return student;
    }
}
执行结果:
序列化成功
反序列化成功
name:张三
sex:male
这个时候没有指定SerialversionUID也是可以成功的,但对象->序列化->存储或传输->反序列化,咱们在反序列化操作之前对Student类修改呢?

这个时候咱们修改一下代码,先注释掉反序列化代码,先进行序列化。

import serialization.entity.Student;

import java.io.*;

public class SerializableTest {
    public static void main(String[] args) throws Exception {
        serializeStudent();
//        Student student = deserializeStudent();
//        System.out.println("name:" + student.getName());
//        System.out.println("sex:" + student.getSex());
    }

    private static void serializeStudent() throws IOException {
        Student student = new Student();
        student.setId(1);
        student.setName("张三");
        student.setSex("male");

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
                new File("F:/student.txt")));
        out.writeObject(student);
        System.out.println("序列化成功");
        out.close();
    }

//    private static Student deserializeStudent() throws Exception {
//        ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("F:/student.txt")));
//        Student student = (Student) in.readObject();
//        System.out.println("反序列化成功");
//        return student;
//    }
}
运行结果:
序列化成功

修改Student类

import lombok.Data;

import java.io.Serializable;

@Data
public class Student implements Serializable {
    private Integer id;
    private String name;
    private String sex;
    private String address;
}
注释掉序列化方法,进行反序列化
import serialization.entity.Student;

import java.io.*;

public class SerializableTest {
    public static void main(String[] args) throws Exception {
//        serializeStudent();
        Student student = deserializeStudent();
        System.out.println("name:" + student.getName());
        System.out.println("sex:" + student.getSex());
    }

//    private static void serializeStudent() throws IOException {
//        Student student = new Student();
//        student.setId(1);
//        student.setName("张三");
//        student.setSex("male");
//
//        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
//                new File("F:/student.txt")));
//        out.writeObject(student);
//        System.out.println("序列化成功");
//        out.close();
//    }

    private static Student deserializeStudent() throws Exception {
        ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("F:/student.txt")));
        Student student = (Student) in.readObject();
        System.out.println("反序列化成功");
        return student;
    }
}
执行结果:
Exception in thread "main" java.io.InvalidClassException: serialization.entity.Student; local class incompatible: stream classdesc serialVersionUID = 3846952599709361171, local class serialVersionUID = -4606152942663467236
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
	at serialization.demo.SerializableTest.deserializeStudent(SerializableTest.java:30)
	at serialization.demo.SerializableTest.main(SerializableTest.java:10)

Process finished with exit code 1
可以看出两次的执行的SerialversionUID不匹配,导致产生java.io.InvalidClassException异常,所以只要指定了SerialversionUID就不会报异常。
//指定serialVersionUID正确写法
private static final long serialVersionUID = 3846952599709361171L;

//如果已经进行序列化了不知道SerialversionUID,可以通过反射获取
Object obj = Student.class.newInstance();
Field field = Student.class.getDeclaredField("serialVersionUID");
field.setAccessible(true);
System.out.println(field.getLong(obj));

最后需要知道的一点就是字节流字符流的区别。
字节流:传输过程中,传输数据的最基本单位是字节的流。
字符流:传输过程中,传输数据的最基本单位是字符的流。

这样讲可能有点不知所云,字节其实就是Java的八大基本类型Byte(比特)单位,而字符通常是’A’、‘B’、’$’、’&'等,字节大小则取决于你是什么编码(环境),如下:

ASCII 码中,一个英文字母(不分大小写)为一个字节,一个中文汉字为两个字节。

UTF-8 编码中,一个英文字为一个字节,一个中文为三个字节。

Unicode 编码中,一个英文为一个字节,一个中文为两个字节。

符号:英文标点为一个字节,中文标点为两个字节。例如:英文句号 . 占1个字节的大小,中文句号 。

占2个字节的大小。UTF-16 编码中,一个英文字母字符或一个汉字字符存储都需要 2 个字节(Unicode 扩展区的一些汉字存储需要 4 个字节)。

UTF-32 编码中,世界上任何字符的存储都需要 4 个字节。

到此这篇关于Java序列化和反序列化示例介绍的文章就介绍到这了,更多相关Java序列化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java序列化常见的三个问题

    1.Java序列化与反序列化是什么? Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程: 序列化:对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性.序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中.核心作用是对象状态的保存与重建. 反序列化:客户端从文件中或网络上获得序列化后的对象字节流,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象. 2.为什么需要序列化与反序列化?

  • 总结Java对象被序列化的两种方法

    Java对象为什么需要被序列化 序列化能够将对象转为二进制流,对象就可以方便的在网络中被传输和保存. 实现序列化的方式 实现Serializable接口 实现Externalizable接口 **这两个接口的区别是:**Serializable接口会自动给对象的所有属性标记为可被序列化.而Externalizable接口默认不给任何属性标记可被序列化,如果需要序列化,需要重写两个方法,分别是writeExternal()和readExternal(),然后在这两个方法中标记需要被序列化的对象属性

  • 深入理解Java序列化与反序列化

    一.前言 序列化:将对象转换为二进制序列在网络中传输或保存到磁盘 反序列化:从网络或磁盘中将二进制序列转换为对象 注意: 对象必须实现Serializable接口 对象的所有属性都要能序列化(Integer,Byte等都进行了序列化) 1.1 String 1.2 Integer 二.案例 2.1 编写大象类 public class Elephant implements Serializable { private String name; private String age; priva

  • 一文带你彻底理解Java序列化和反序列化

    Java序列化是什么? Java序列化是指把Java对象转换为字节序列的过程,Java反序列化是指把字节序列恢复为Java对象的过程. 反序列化: 客户端重文件,或者网络中获取到文件以后,在内存中重构对象. 序列化: 对象序列化的最重要的作用是传递和保存对象的时候,保证对象的完整性和可传递性.方便字节可以在网络上传输以及保存在本地文件. 为什么需要序列化和反序列化 实现分布式 核心在于RMI,可以利用对象序列化运行远程主机上的服务,实现运行的时候,就像在本地上运行Java对象一样. 实现递归保存

  • 图文浅析Java序列化和反序列化

    序列化 序列化:将对象转换为二进制序列在网络中传输或保存到磁盘 反序列化:从网络或磁盘中将二进制序列转换为对象 注意: 对象必须实现Serializable接口 对象的所有属性都要能序列化(Integer,Byte等都进行了序列化) String Integer 案例: 1.编写大象类 public class Elephant implements Serializable { private String name; private String age; private String se

  • Java序列化和反序列化示例介绍

    以前用序列化都是一些方法需要才实现的,后来业务需求要深拷贝才去研究.参阅了别人博客得出一些总结. 序列化是为了把Java对象转化为字节序列(字节流)的过程.然后深拷贝是通过对流的操作来实现的,序列化后数据方便存储和传输.反序列化则是把字节序列反序列化为Java对象 存储方便:因为对象会被回收,序列化后可以持续化存储在磁盘中传输方便:字节序列(二进制形式)可以进行网络传输和传播. 最好设置一个SerialversionUID,因为序列化和反序列化是对比SerialversionUID来进行的,虽然

  • java 对象的序列化和反序列化详细介绍

    最近周末,对java 的基础知识做了一个整理,其中java 序列化和反序列化的资料进行了详细整理,这里做个笔记,希望也能帮助到读到此文的朋友. 一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是

  • JAVA序列化和反序列化的底层实现原理解析

    一.基本概念 1.什么是序列化和反序列化 (1)Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程: (2)**序列化:**对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性.序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中.序列化后的字节流保存了Java对象的状态以及相关的描述信息.序列化机制的核心作用就是对象状态的保存与重建. (3)**反序列化:**客户端从文件中或网络上获得序列化后

  • java序列化与反序列化操作实例分析

    本文实例分析了java序列化与反序列化操作.分享给大家供大家参考,具体如下: 概述: Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程. 示例代码: import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.i

  • 详解Java 序列化与反序列化(Serialization)

    一.什么是?为什么需要? 序列化(Serialization)是将对象的状态信息转化为可以存储或者传输的形式的过程,反序列化则为其逆过程. 内存的易失性:传输需要:一些应用场景中需要将对象持久化下来,以便在需要的时候进行读取. 二.JDK提供的API java.io.ObjectOutputStream类的 writeObject(Object obj)方法 java.io.ObjectInputStream类的readObject()方法 对于Serializable,如果没有重写 write

  • java序列化与反序列化的使用方法汇总

    一.概念 java对象序列化的意思就是将对象的状态转化成字节流,以后可以通过这些值再生成相同状态的对象.对象序列化是对象持久化的一种实现方法,它是将对象的属性和方法转化为一种序列化的形式用于存储和传输.反序列化就是根据这些保存的信息重建对象的过程. 序列化:将java对象转化为字节序列的过程. 反序列化:将字节序列转化为java对象的过程. 二.为什么要序列化和反序列化 我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本.图片.音频.视频等, 而这些数据都会以二进制序列的形

  • Java 序列化和反序列化实例详解

    Java 序列化和反序列化实例详解 在分布式应用中,对象只有经过序列化才能在各个分布式组件之间传输,这就涉及到两个方面的技术-发送者将对象序列化,接受者将对象反序列化,下面就是一个很好的例子! 1.实体-Employee import java.io.Serializable; public class Employee implements Serializable{ /** * */ private static final long serialVersionUID = 1L; publi

  • java 序列化与反序列化的实例详解

     1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程.  2.为什么需要序列化与反序列化 我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本.图片.音频.视频等, 而这些数据都会以二进制序列的形式在网络上传送.那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的.如何做到呢?这就需要Java序列化与反序列化了.换句话说,一方面,发送方需要把这个Java对象转换为字

随机推荐