在java序列化中,如果有些字段不想进行序列化,可以使用transient关键字来标记这些字段。被标记为transient的字段在序列化过程中会被忽略,不会被写入到序列化流中。
使用transient关键字
示例
import java.io.*;
Class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private transient String password;//不想被序列化的字段
public User(String username,String password){
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "User{username='" + username + "', password='" + password + "'}";
}
public class TransientExample {
public static void main (String[] args){
User user = new User("john_doe","secret_password");
//序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))){
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}
//反序列化
User deserializedUser = null;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))){
deserializedUser = (User) ois.readObject();
} catch (IOException | ClassNotFoundException e){
e.printStackTrace();
}
}
// 打印反序列化后的对象
System.out.println(deserializedUser);
}
}
}
在这个示例中,User类中的password字段被标记为transient,因此它不会被序列化,运行上述代码后,反序列化后的User对象的password字段将为bull
自定义序列化方法
除了使用transient关键字,还可以通过实现Serializable接口的自定义序列化方法来扩展序列化过程,这些方法是writeObject和readObject。
示例
import java.io.*;
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private transient String password; // 不想序列化的字段
public User(String username, String password) {
this.username = username;
this.password = password;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject(); // 序列化非transient字段
oos.writeObject(encryptPassword(password)); // 自定义序列化password
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject(); // 反序列化非transient字段
this.password = decryptPassword((String) ois.readObject()); // 自定义反序列化password
}
private String encryptPassword(String password) {
// 简单加密示例(实际使用中请使用更安全的加密方法)
return "encrypted_" + password;
}
private String decryptPassword(String encryptedPassword) {
// 简单解密示例(实际使用中请使用更安全的解密方法)
return encryptedPassword.replace("encrypted_", "");
}
@Override
public String toString() {
return "User{username='" + username + "', password='" + password + "'}";
}
}
public class CustomSerializationExample {
public static void main(String[] args) {
User user = new User("john_doe", "secret_password");
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}
// 反序列化
User deserializedUser = null;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {
deserializedUser = (User) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
// 打印反序列化后的对象
System.out.println(deserializedUser);
}
}
在这个示例中,自定义的writeObject和readObject方法允许我们在序列化和反序列化过程中对password字段进行加密和解密操作,从而控制其序列化行为。