序列化是将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 是一个序列化版本号。如果你的类在序列化之后进行了修改(比如新增了字段),那么在反序列化的时候,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号