动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

Java的序列化与反序列化

06-20 18:47 348浏览
举报 T字号
  • 大字
  • 中字
  • 小字

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象同理,反序列化就是把字节序列恢复为Java对象的过程。通俗易懂的来说就好比好莱坞大片里面的瞬移,将一个人或者物体变成一串数字和字母流,然后传送到很远的地方再将这一串数字和字母流变回原来的物体。这一过程和java的序列化反序列化很像,将物体变成数字字母流就是序列化,将数字字母流变成物体就是反序列化。通常,对象实例的所有字段都会被序列化,这意味着数据会被表示为实例的序列化数据。这样,能够解释该格式的代码有可能能够确定这些数据的值,而不依赖于该成员的可访问性。类似地,反序列化从序列化的表示形式中提取数据,并直接设置对象状态,这也与可访问性规则无关。

对于任何可能包含重要的安全性数据的对象,如果可能,应该使该对象不可序列化。如果它必须为可序列化的,请尝试生成特定字段来保存不可序列化的重要数据。如果无法实现这一点,则应注意该数据会被公开给任何拥有序列化权限的代码,并确保不让任何恶意代码获得该权限。

简单来说就好比我们看大科幻电影 里面有很多的情节是这样的 将一个人或者物体变成一串数字和字母流 然后传送到很远的地方再将这一串数字和字母流变回原来的物体 这一过程和序列化反序列化很像 将物体变成数字字母流就是序列化 将数字字母流变成物体就是反序列化

在实现Java对象的序列化与反序列化的过程中我们需要注意以下几点:

1.如果对象要进行序列化需要实现Serializable接口

2.ObjectOutputStream 用于序列化

3.ObjectInputStream 用于反序列化

4.transient修饰的变量不可以序列化

5.static 修饰的变量不能被序列化

实现java对象的序列化与反序列化的代码实现如下:

import java.io.*;

//实现serializable接口才可以实现对象的序列化

class Person implements Serializable {

    public String name;

    public int age;

    public String sex;

    //transient修饰的变量不可以序列化

    transient public String cardId;

    //static 修饰的变量不能被序列化

    public static String phoneNum;

    public Person(String name, int age, String sex, String cardId) {

        this.name = name;

        this.age = age;

        this.sex = sex;

        this.cardId = cardId;

    }

    public static void setPhoneNum(String phoneNum) {

        Person.phoneNum = phoneNum;

    }

    @Override

    public String toString() {

        return "Person{" +

                "name='" + name + '\'' +

                ", age=" + age +

                ", sex='" + sex + '\'' +

                ", cardId='" + cardId + '\'' +

                ", phoneNum='" + phoneNum + '\'' +

                '}';

    }

}

public class SerializTest {

    public static void main(String[] args) {

        Person.person = new Person("Listen", 21, "MAN", "100100100111");

        Person.setPhoneNum("120");

        //序列化一个对象

        serializPreson(person);

        //反序列化一个对象

        Person personRet = desSerializable();

        System.out.println(personRet);

    }

    private static Person desSerializable() {

        Person person = null;

        try (ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\java\\java.txt"))){

            person = (Person) objectInputStream.readObject();

            System.out.println("反序列化成功");

        } catch (IOException | ClassNotFoundException e) {

            e.getStackTrace();

        }

        return person;

    }

    private static void serializPreson(Person person) {

        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\java\\java.txt"))){

            //将person对象序列化输入文件

            // 这个 writeObject 集序列化+写文件 两者同时搞定

            objectOutputStream.writeObject(person);

            System.out.println("序列化成功");

        } catch (IOException e) {

            e.getStackTrace();

        }

    }

}

从上面的结果我们可以看到cardId被transient修饰不能被序列化,所以得到的反序列化结果他的值就是null 。但是我们说被static修饰的phoneNum也不能序列化,但是此处它尽然不显示null,这是因为他是静态变量,在代码编译期间就已经存储在方法区的,所以他不需要序列化也可以获得值。

一个类如果想被序列化,需要实现一个Serialzable接口。类中的静态变量的值是不会进行序列化的,transient修饰的属性,是不会被序列化的,内置类型为对应的0值。引用类型为null。在实现这个Serializable接口的时候,一定要给这个serialVersionUID赋值,最好设置为1L,不同的serialVersionUID的值,会影响到反序列化。掌握了java序列化与反序列化,能够让我们对系统的性能有更好的提升,使程序更具维护性。

0人推荐
共同学习,写下你的评论
0条评论
冷酷自尊VIP
程序员冷酷自尊VIP

5篇文章贡献26210字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

五分钟读懂UML类图

江湖人称小李白12-10 10:41

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消