序列化和反序列化的介绍
将类的对象写入文件,并可以通过文件恢复原来的对象,这便是序列化与反序列化;
对于需要写入读出的类需要实现 Serializable或Externalizable,实现 Serializable接口较为简单一些
关于 Serializable 与 Externalizable 的对比,可以简单归结为:Externalizable 是 Serializable 的子接口,里面给出了抽象方法,要求实现类进行重写,方便对部分属性进行序列化
实现Serializable接口的序列化与反序列化
这个不要求类具有空构造函数,且实现较为简单,推荐使用这个
同时只会对没有 static / transient 修饰的属性进行序列化
进行序列化与反序列化的时候需要注意的问题:包的位置,在进行序列化的时候会将包的信息写入,所以需要共用同一个包下的同一个类;以及对象序列化时需要实现 Serializable接口,如果成员也是类的对象的时候,也需要实现 Serializable接口(如果父类已经实现过则会继承给子类,所以这时子类是不用再实现Serializable接口的)
package com.boot.test;
import java.io.*;
import java.nio.file.Files;
/**
* @author bbyh
* @date 2022/11/2 0002 10:19
* @description
*/
public class FileTest implements Serializable {
private static final long serialVersionUID = 1L;
private final String name;
private final Integer age;
public FileTest(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "FileTest{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
public static void main(String[] args) {
test1();
test2();
}
public static void test1() {
File file = new File("D:/test.txt");
try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
outputStream.writeObject(new FileTest("Jack", 20));
System.out.println("Write Success");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void test2() {
File file = new File("D:/test.txt");
try (ObjectInputStream inputStream = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
FileTest fileTest = (FileTest) inputStream.readObject();
System.out.println(fileTest);
System.out.println("Read Success");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
实现Externalizable接口的序列化与反序列化
Externalizable 接口是实现了 Serializable 接口的
这个接口实现序列化,我真没搞懂,感觉挺鸡肋的,不是必须要无参构造,即你可以直接读入,然后通过有参构造创建对象,但是有无参构造会书写规范一些
另外,我通过直接像 Serializable 接口一样直接写入整个对象时,一直无法正确读出对象,必须要一个一个写入才行,感觉不好用
package com.boot.test;
import java.io.*;
import java.nio.file.Files;
/**
* @author bbyh
* @date 2022/11/2 0002 10:19
* @description
*/
public class FileTest implements Externalizable {
private static final long serialVersionUID = 1L;
private String name;
private Integer age;
public FileTest(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "FileTest{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
public static void main(String[] args) {
FileTest fileTest = new FileTest("Jack", 20);
fileTest.test1();
fileTest.test2();
}
public void test1() {
File file = new File("D:/test.txt");
try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
writeExternal(outputStream);
System.out.println("Write Success");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void test2() {
File file = new File("D:/test.txt");
try (ObjectInputStream inputStream = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
readExternal(inputStream);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.name);
out.writeObject(this.age);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
FileTest fileTest = new FileTest((String) in.readObject(), (Integer) in.readObject());
// fileTest.name = (String) in.readObject();
// fileTest.age = (Integer) in.readObject();
System.out.println(fileTest);
System.out.println("Read Success");
}
}
当然也可以通过自己的代码写,就不在需要实现的方法里面写;只是这样的话,代码确实会较为混乱一些
这样的情况下,同样是无法直接一次性写入全部的对象,需要一个个写入,不能说一点用都没有,只能说看着也不想用
package com.boot.test;
import java.io.*;
import java.nio.file.Files;
/**
* @author bbyh
* @date 2022/11/2 0002 10:19
* @description
*/
public class FileTest implements Externalizable {
private static final long serialVersionUID = 1L;
private String name;
private Integer age;
public FileTest(String name, Integer age) {
this.name = name;
this.age = age;
}
public FileTest() {
}
@Override
public String toString() {
return "FileTest{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
public static void main(String[] args) {
test1();
test2();
}
public static void test1() {
File file = new File("D:/test.txt");
try (ObjectOutputStream outputStream = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
FileTest fileTest = new FileTest("jack", 20);
outputStream.writeObject(fileTest.name);
outputStream.writeObject(fileTest.age);
System.out.println("Write Success");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void test2() {
File file = new File("D:/test.txt");
try (ObjectInputStream inputStream = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
FileTest fileTest = new FileTest();
fileTest.name = (String) inputStream.readObject();
fileTest.age = (Integer) inputStream.readObject();
System.out.println(fileTest);
System.out.println("Read Success");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}