Java序列化與反序列化,有哪些坑需要注意!
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
1.序列化與反序列化的概念
public class People {
private Long id;
public People(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
'}';
}
}
import java.io.*;
// 屏蔽編譯器的警告
@SuppressWarnings("all")
public class Main {
/**
* <h1>序列化和反序列化 People 對象</h1>
*/
private static void testSerializablePeople() throws Exception {
// 序列化的步驟
// 用于存儲(chǔ)序列化的文件,這里的java_下劃線僅僅為了說明是java序列化對象,沒有任何其他含義
File file = new File("/tmp/people_10.java_");
if (!file.exists()) {
// 1,先得到文件的上級(jí)目錄,并創(chuàng)建上級(jí)目錄
file.getParentFile().mkdirs();
try {
// 2,再創(chuàng)建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
People p = new People(10L);
// 創(chuàng)建一個(gè)輸出流
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file)
);
// 輸出可序列化對象
oos.writeObject(p);
// 關(guān)閉輸出流
oos.close();
// 反序列化的步驟
// 創(chuàng)建一個(gè)輸入流
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(file)
);
// 得到反序列化的對象,這里可以強(qiáng)轉(zhuǎn)為People類型
Object newPerson = ois.readObject();
// 關(guān)閉輸入流
ois.close();
System.out.println(newPerson);
}
public static void main(String[] args) throws Exception {
testSerializablePeople();
}
}


2.子類實(shí)現(xiàn)Serializable接口,父類沒有實(shí)現(xiàn),子類可以序列化嗎?
public class Worker extends People implements Serializable {
private String name;
private Integer age;
public Worker(Long id, String name, Integer age) {
super(id);
this.name = name;
this.age = age;
}
}
public static void main(String[] args) throws Exception {
testSerizableWorker();
}
/**
* <h2>子類實(shí)現(xiàn)序列化, 父類不實(shí)現(xiàn)序列化</h2>
* */
private static void testSerizableWorker() throws Exception {
File file = new File("/tmp/worker_10.java_");
if (!file.exists()) {
// 1,先得到文件的上級(jí)目錄,并創(chuàng)建上級(jí)目錄
file.getParentFile().mkdirs();
try {
// 2,再創(chuàng)建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Worker p = new Worker(10L, "lcy", 18);
// 創(chuàng)建一個(gè)輸出流
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file)
);
// 輸出可序列化對象
oos.writeObject(p);
// 關(guān)閉輸出流
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object newWorker = ois.readObject(); // 父類沒有序列化的時(shí)候,需要調(diào)用父類的無參數(shù)構(gòu)造方法
ois.close();
System.out.println(newWorker);
}



3.類中存在引用對象,這個(gè)類對象在什么情況下可以實(shí)現(xiàn)序列化?
public class Combo implements Serializable {
private int id;
private People people;
public Combo(int id, People people) {
this.id = id;
this.people = people;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
@Override
public String toString() {
return "Combo{" +
"id=" + id +
", people=" + people +
'}';
}
}
public class People {
private Long id;
public People() {
}
public People(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
'}';
}
}
private static void testSerializableCombo() throws Exception {
File file = new File("/tmp/combo_10.java_");
if (!file.exists()) {
// 1,先得到文件的上級(jí)目錄,并創(chuàng)建上級(jí)目錄
file.getParentFile().mkdirs();
try {
// 2,再創(chuàng)建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Combo p = new Combo(1, new People(10L));
// 創(chuàng)建一個(gè)輸出流
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(file)
);
// 輸出可序列化對象
oos.writeObject(p);
// 關(guān)閉輸出流
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object newCombo = ois.readObject();
ois.close();
System.out.println(newCombo);
}
public static void main(String[] args) throws Exception {
testSerializableCombo();
}


4.同一個(gè)對象多次序列化之間有屬性更新,前后的序列化有什么區(qū)別?
/**
* <h2>同一個(gè)對象多次序列化的問題, 坑</h2>
* */
private static void sameObjectRepeatedSerialization() throws Exception {
File file = new File("/tmp/peopele_more.java_");
if (!file.exists()) {
// 1,先得到文件的上級(jí)目錄,并創(chuàng)建上級(jí)目錄
file.getParentFile().mkdirs();
try {
// 2,再創(chuàng)建文件
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
People p = new People(10L);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
// 未序列化,先修改屬性
p.setId(11L);
oos.writeObject(p);
// 序列化一次后,再次修改屬性
p.setId(15L);
oos.writeObject(p);
// 序列化兩次后,再次修改屬性
p.setId(20L);
oos.writeObject(p);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object people1 = ois.readObject();
Object people2 = ois.readObject();
Object people3 = ois.readObject();
ois.close();
System.out.println(((People) people1).getId());
System.out.println(((People) people2).getId());
System.out.println(((People) people3).getId());
}
public static void main(String[] args) throws Exception {
sameObjectRepeatedSerialization();
}


作者 | 磚業(yè)洋__
來源 | https://blog.csdn.net/qq_34115899/article/details/118463573

評(píng)論
圖片
表情
