序列化的目的
- 跨平台存储
- 网络传输
序列化的方式
jdk原生
序列化与反序列化
@Test
public void test01() throws Exception {
//序列化
FileOutputStream fileOutputStream = new FileOutputStream("D:\\IDEA_file\\Learn_8\\src\\file\\person.dat");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeBoolean(true);//boolean -> Boolean;
Person person = new Person(10, "小明");
//序列化对象
objectOutputStream.writeObject(person);
//关闭外层流
objectOutputStream.close();
}
@Test
public void test02() throws Exception {
//反序列化
FileInputStream fileInputStream = new FileInputStream("D:\\IDEA_file\\Learn_8\\src\\file\\person.dat");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
boolean b = objectInputStream.readBoolean();
System.out.println(b);
Object o = objectInputStream.readObject();
System.out.println(o);
//向下转型
Person p=(Person) o;
System.out.println(p.toString());
objectInputStream.close();
}
要求
被序列化的类实现Serializable接口
例如:
public final class String
implements java.io.Serializable
public class Person implements Serializable
serialVersionUID
作用:
标记一个类的版本,如果我们不指定版本号,每当我们修改或添加一个类的字段或者方法,jdk就会自动根据属性和方法等参数生成一个id号
反序列化的时候的id号和序列化时候的id号不一致就会反序列化失败
java.io.InvalidClassException: file.Person; local class incompatible: stream classdesc serialVersionUID = 7330609361009257993, local class serialVersionUID = -3573391668384454971
因此我们一般都会自己指定版本号,该字段必须是静态的、最终的和类型:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
不能被继承
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
}
- 当兼容升级的时候,不修改版本号
- 当不兼容升级的时候,修改版本号
[!Note] tip
避免被序列化
static
static
变量因为不属于任何对象(Object),所以无论有没有 transient
关键字修饰,均不会被序列化。
transient
如果有些字段不想进行序列化,
对于不想进行序列化的变量,使用 transient
关键字修饰。
transient
关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient
修饰的变量值不会被持久化和恢复。
关于 transient
还有几点注意:
transient
只能修饰变量,不能修饰类和方法。transient
修饰的变量,在反序列化后变量值将会被置成类型的默认值。例如,如果是修饰int
类型,那么反序列后结果就是0
。
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
Integer age;
String name;
static Integer total=10;
transient Integer tall=178;
}
json
fastjson
@Test
public void test1(){
User user = new User("张三",1);
System.out.println(user);
System.out.println("-----fastjson-----");
// 将Java对象转换为json字符串
String jsonString=JSON.toJSONString(user);
System.out.println(jsonString);
// 将json反序列化为Java对象
User user1 = JSON.parseObject(jsonString,User.class);
System.out.println(user1);
}
package com.gdb.mvc.controller;
import java.io.Serializable;
/**
* @Author gao
* @Description TODO
* @Date 2023/6/11 15:52
* @Version 1.0
*/public class User {
String name;
Integer age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}