通过 Serializable 接口实现序列化时,默认会将全部字段进行持久化。
但出于安全考虑,部分敏感字段,比如:密码,我们并不希望它也被持久化。
public class User implements Serializable {
private String name;
private String password;
public User(String name, String password) {
this.name = name;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
public class UserSerializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user = new User("admin", "123456");
System.out.println(user);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.out"));
out.writeObject(user);
out.close();
System.out.println("------反序列化------");
ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.out"));
user = (User) in.readObject();
System.out.println(user);
}
}
User{name='admin', password='123456'}
------反序列化------
User{name='admin', password='123456'}
下面,给大家演示屏蔽部分字段的两种方式。
序列化屏蔽字段的方式
1. transient 限时关键字
transient 的用法非常简单,直接修饰需要关闭序列化的字段即可。
public class User implements Serializable {
private String name;
private transient String password;
public User(String name, String password) {
this.name = name;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
public class UserSerializable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user = new User("admin", "123456");
System.out.println(user);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.out"));
out.writeObject(user);
out.close();
System.out.println("------反序列化------");
ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.out"));
user = (User) in.readObject();
System.out.println(user);
}
}
User{name='admin', password='123456'}
------反序列化------
User{name='admin', password='null'}
2. Externalizable 接口
Externalizable 接口不会自动存储和恢复字段的值,必须由我们自己覆写 writeExternal() 和 readExternal() 方法,手动保存/恢复持久化的字段,未操作的字段将不会被持久化。
实现 Externalizable 接口的类,必须提供无参构造方法;Serializable 接口则不需要,它是基于二进制为基础来构造对象的。
public class User implements Externalizable {
private String name;
private String password;
public User(String name, String password) {
this.name = name;
this.password = password;
}
public User() {
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(name);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name = (String) in.readObject();
}
}
public class UserExternalizable {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user = new User("admin", "123456");
System.out.println(user);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.out"));
out.writeObject(user);
out.close();
System.out.println("------反序列化------");
ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.out"));
user = (User) in.readObject();
System.out.println(user);
}
}
User{name='admin', password='123456'}
------反序列化------
User{name='admin', password='null'}
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!