当前位置: 首页 > 图灵资讯 > 技术篇> Java的序列化与反序列化

Java的序列化与反序列化

来源:图灵教育
时间:2023-04-09 09:43:01

序列化 (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序列化和反序列化可以更好地提高系统的性能,使程序更具维护性。