本文目录导读:

在Java中,反序列化对象是将之前通过序列化保存的字节流重新恢复为Java对象的过程,以下是完整的案例说明:
基本反序列化示例
首先创建一个可序列化的类
import java.io.Serializable;
public class Person implements Serializable {
// 序列化版本号,建议显式声明
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String email;
// transient关键字修饰的字段不会被序列化
private transient String password;
public Person(String name, int age, String email, String password) {
this.name = name;
this.age = age;
this.email = email;
this.password = password;
}
// getter和setter方法
public String getName() { return name; }
public int getAge() { return age; }
public String getEmail() { return email; }
public String getPassword() { return password; }
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age +
", email='" + email + "', password='" + password + "'}";
}
}
反序列化方法
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
public class DeserializationExample {
public static void main(String[] args) {
String filename = "person.ser";
// 从文件反序列化对象
Person person = deserializeFromFile(filename);
if (person != null) {
System.out.println("反序列化成功!");
System.out.println(person);
// password是transient,所以会为null
System.out.println("Password (transient): " + person.getPassword());
}
}
/**
* 从文件反序列化对象
*/
public static Person deserializeFromFile(String filename) {
Person person = null;
try (FileInputStream fileIn = new FileInputStream(filename);
ObjectInputStream in = new ObjectInputStream(fileIn)) {
// 读取对象
person = (Person) in.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
System.err.println("反序列化失败: " + e.getMessage());
}
return person;
}
}
多种反序列化方式
import java.io.*;
import java.util.Base64;
public class MultipleDeserializationMethods {
/**
* 从文件反序列化
*/
public static Object fromFile(String filePath) throws Exception {
try (FileInputStream fis = new FileInputStream(filePath);
ObjectInputStream ois = new ObjectInputStream(fis)) {
return ois.readObject();
}
}
/**
* 从字节数组反序列化
*/
public static Object fromByteArray(byte[] data) throws Exception {
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bais)) {
return ois.readObject();
}
}
/**
* 从Base64字符串反序列化
*/
public static Object fromBase64String(String base64Str) throws Exception {
byte[] data = Base64.getDecoder().decode(base64Str);
return fromByteArray(data);
}
/**
* 从输入流反序列化
*/
public static Object fromInputStream(InputStream inputStream) throws Exception {
try (ObjectInputStream ois = new ObjectInputStream(inputStream)) {
return ois.readObject();
}
}
// 使用示例
public static void main(String[] args) {
try {
// 1. 从文件
Person person1 = (Person) fromFile("person.ser");
// 2. 从字节数组
byte[] data = /* 获取字节数组 */;
Person person2 = (Person) fromByteArray(data);
// 3. 从Base64字符串
String base64Str = /* 获取Base64字符串 */;
Person person3 = (Person) fromBase64String(base64Str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
安全性考虑 - 验证反序列化
import java.io.*;
import java.util.Arrays;
import java.util.List;
public class SafeDeserialization {
// 白名单 - 允许反序列化的类
private static final List<String> WHITE_LIST = Arrays.asList(
"Person",
"java.lang.String",
"java.util.ArrayList"
);
/**
* 安全的反序列化(使用白名单)
*/
public static Object safeDeserialize(byte[] data) throws Exception {
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
SafeObjectInputStream sois = new SafeObjectInputStream(bais)) {
return sois.readObject();
}
}
/**
* 自定义ObjectInputStream,实现白名单验证
*/
static class SafeObjectInputStream extends ObjectInputStream {
public SafeObjectInputStream(InputStream in) throws IOException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
String className = desc.getName();
// 检查是否在白名单中
if (!isWhitelisted(className)) {
throw new SecurityException("反序列化被拒绝: " + className);
}
return super.resolveClass(desc);
}
private boolean isWhitelisted(String className) {
for (String allowed : WHITE_LIST) {
if (className.contains(allowed)) {
return true;
}
}
return false;
}
}
}
完整示例 - 序列化和反序列化
import java.io.*;
public class CompleteExample {
public static void main(String[] args) {
// 1. 创建原始对象
Person originalPerson = new Person("张三", 25, "zhangsan@example.com", "123456");
System.out.println("原始对象: " + originalPerson);
// 2. 序列化到文件
try (FileOutputStream fos = new FileOutputStream("person.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(originalPerson);
System.out.println("序列化成功!");
} catch (IOException e) {
e.printStackTrace();
}
// 3. 从文件反序列化
try (FileInputStream fis = new FileInputStream("person.ser");
ObjectInputStream ois = new ObjectInputStream(fis)) {
Person deserializedPerson = (Person) ois.readObject();
System.out.println("反序列化后的对象: " + deserializedPerson);
// 验证反序列化结果
System.out.println("\n验证结果:");
System.out.println("Name: " + deserializedPerson.getName());
System.out.println("Age: " + deserializedPerson.getAge());
System.out.println("Email: " + deserializedPerson.getEmail());
// transient字段为null
System.out.println("Password (应为null): " + deserializedPerson.getPassword());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
注意事项
- 版本控制:始终声明
serialVersionUID - 安全性:反序列化可能存在安全风险,建议使用白名单验证
- 异常处理:处理好 IOException 和 ClassNotFoundException
- transient关键字:标记的字段不会被序列化/反序列化
- 资源管理:使用 try-with-resources 自动关闭流
常见问题解决
// 当serialVersionUID不匹配时的处理
public class CompatiblePerson implements Serializable {
// 使用默认值,允许向后兼容
private static final long serialVersionUID = 1L;
// 添加新字段时的处理
private String newField;
// 自定义反序列化逻辑
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
// 执行默认反序列化
in.defaultReadObject();
// 执行自定义逻辑
if (newField == null) {
newField = "默认值";
}
}
}
这就是Java反序列化的完整案例,涵盖了基本用法、多种方式、安全性考虑和最佳实践。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播