序列化是将java对象转换为字节流以便存储或传输的过程,反序列化则是将其还原为对象。要实现序列化,类需实现serializable接口,如public class myobject implements serializable,并可显式声明serialversionuid以保证版本一致性。可通过transient关键字忽略某些字段,或通过自定义writeobject和readobject方法控制序列化逻辑。反序列化存在安全风险,应避免反序列化不受信任的数据、使用安全框架、白名单机制、升级java版本及利用工具检测漏洞。

序列化,简单来说,就是把Java对象转换成字节流的过程,方便存储或者网络传输。反序列化则是反过来,把字节流还原成Java对象。要让一个Java对象可以被序列化,就得让它的类实现 Serializable 接口。

Serializable 接口本身是个标记接口,里面没有任何方法需要实现。它的作用就像盖了个章,告诉JVM:“嘿,这个类的对象可以被序列化!”

解决方案
立即学习“Java免费学习笔记(深入)”;

实现 Serializable 接口:
import java.io.Serializable;
public class MyObject implements Serializable {
private String name;
private int age;
public MyObject(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and setters (optional, but recommended)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "MyObject{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}序列化对象:
import java.io.*;
public class SerializationExample {
public static void main(String[] args) {
MyObject obj = new MyObject("Alice", 30);
try (FileOutputStream fileOut = new FileOutputStream("myobject.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
out.writeObject(obj);
System.out.println("Serialized data is saved in myobject.ser");
} catch (IOException i) {
i.printStackTrace();
}
}
}反序列化对象:
import java.io.*;
public class DeserializationExample {
public static void main(String[] args) {
MyObject obj = null;
try (FileInputStream fileIn = new FileInputStream("myobject.ser");
ObjectInputStream in = new ObjectInputStream(fileIn)) {
obj = (MyObject) in.readObject();
System.out.println("Deserialized MyObject...");
System.out.println(obj); // Output: MyObject{name='Alice', age=30}
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("MyObject class not found");
c.printStackTrace();
return;
}
}
}serialVersionUID,为什么需要它?serialVersionUID 是一个序列化版本号。如果你的类在序列化之后进行了修改(比如新增了字段),那么在反序列化的时候,JVM会检查这个版本号。如果版本号不一致,就会抛出 InvalidClassException 异常。
简单来说,就是为了保证序列化和反序列化的一致性。 建议显式地声明一个 serialVersionUID,即使类结构发生变化,只要这个ID不变,反序列化就能成功(当然,前提是修改不是特别剧烈)。
import java.io.Serializable;
public class MyObject implements Serializable {
private static final long serialVersionUID = 1L; // 显式声明
private String name;
private int age;
// ... (rest of the class)
}有时候,你可能不想序列化某个字段,比如密码或者一些敏感信息。这时候,你可以使用 transient 关键字来标记这个字段。被 transient 标记的字段在序列化的时候会被忽略,反序列化后会变成默认值(比如 null 对于对象,0 对于 int)。
import java.io.Serializable;
public class MyObject implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private transient String password; // 不会被序列化
private int age;
public MyObject(String name, String password, int age) {
this.name = name;
this.password = password;
this.age = age;
}
// ... (rest of the class)
}你还可以通过实现 writeObject 和 readObject 方法来完全控制序列化和反序列化的过程。这允许你自定义序列化的逻辑,比如加密某些字段,或者进行一些数据转换。
import java.io.*;
public class MyObject implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String password;
private int age;
// ... (constructor and getters/setters)
private void writeObject(ObjectOutputStream out) throws IOException {
// 自定义序列化逻辑,比如加密 password
String encryptedPassword = encrypt(password);
out.defaultWriteObject(); // 先序列化其他字段
out.writeObject(encryptedPassword); // 序列化加密后的密码
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// 自定义反序列化逻辑,比如解密 password
in.defaultReadObject(); // 先反序列化其他字段
String encryptedPassword = (String) in.readObject(); // 读取加密后的密码
this.password = decrypt(encryptedPassword); // 解密密码
}
private String encrypt(String password) {
// 实际的加密逻辑
return "ENCRYPTED_" + password;
}
private String decrypt(String encryptedPassword) {
// 实际的解密逻辑
return encryptedPassword.substring(10); // 简单地移除 "ENCRYPTED_" 前缀
}
}序列化和反序列化最大的安全风险在于反序列化漏洞。攻击者可以构造恶意的序列化数据,在反序列化过程中执行任意代码。
避免反序列化漏洞的一些方法:
总而言之,理解序列化的机制,以及潜在的安全风险,才能更好地保护你的应用。
以上就是Java中如何实现序列化 掌握Serializable的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号