Java 序列化与反序列化
Java 序列化是将一个对象转化为字节流的过程,可以用于对象的存储、传输以及远程调用等。Java 反序列化是将字节流转化为对象的过程。
Java 提供了两种实现序列化和反序列化的方式:
使用 Serializable 接口
可以让一个类实现 Serializable 接口,该接口没有方法,只是起到标识作用。使用 ObjectOutputStream 类的 writeObject() 方法可以将一个对象序列化为字节流,使用 ObjectInputStream 类的 readObject() 方法可以将字节流反序列化为对象。
示例代码:
import java.io.*;
class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private transient String password; // transient 关键字表示该字段不会被序列化
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
public class SerializationExample {
public static void main(String[] args) {
User user = new User("admin", "123456");
try {
// 序列化对象
FileOutputStream fileOutputStream = new FileOutputStream("user.ser");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(user);
objectOutputStream.close();
fileOutputStream.close();
System.out.println("Object serialized successfully.");
// 反序列化对象
FileInputStream fileInputStream = new FileInputStream("user.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
User deserializedUser = (User) objectInputStream.readObject();
objectInputStream.close();
fileInputStream.close();
System.out.println("Object deserialized successfully.");
System.out.println("Username: " + deserializedUser.getUsername());
System.out.println("Password: " + deserializedUser.getPassword());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
使用 Externalizable 接口
如果一个类实现 Externalizable 接口,则必须实现其中的 readExternal() 和 writeExternal() 方法,可以在这两个方法中指定对象的序列化和反序列化方式。
示例代码:
import java.io.*;
class User implements Externalizable {
private String username;
private transient String password;
public User() {
// 默认构造方法,必须提供
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(username);
out.writeObject(password);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
username = (String) in.readObject();
password = (String) in.readObject();
}
}
public class SerializationExample {
public static void main(String[] args) {
User user = new User("admin", "123456");
try {
// 序列化对象
FileOutputStream fileOutputStream = new FileOutputStream("user.ser");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(user);
objectOutputStream.close();
fileOutputStream.close();
System.out.println("Object serialized successfully.");
// 反序列化对象
FileInputStream fileInputStream = new FileInputStream("user.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
User deserializedUser = (User) objectInputStream.readObject();
objectInputStream.close();
fileInputStream.close();
System.out.println("Object deserialized successfully.");
System.out.println("Username: " + deserializedUser.getUsername());
System.out.println("Password: " + deserializedUser.getPassword());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
需要注意的是,被序列化的类必须实现 Serializable 或 Externalizable 接口。同时,要保证序列化和反序列化的类的 serialVersionUID 属性保持一致,否则可能导致反序列化失败。另外,transient 关键字用于标记不需要被序列化的字段。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Java 关键字 default 剖析
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论