Customizing serialization in Java allows you to define exactly how an object is serialized and deserialized. This can be particularly useful when you need to control the process of saving and restoring the state of an object. Below is a simple example demonstrating how to implement the `readObject` and `writeObject` methods to customize the serialization behavior of a class.
import java.io.*;
class User implements Serializable {
private String username;
private transient String password; // transient fields are not serialized
public User(String username, String password) {
this.username = username;
this.password = password;
}
// Custom serialization
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject(); // default serialization
oos.writeObject(encryptPassword(password)); // encrypt password
}
// Custom deserialization
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject(); // default deserialization
password = decryptPassword((String) ois.readObject()); // decrypt password
}
private String encryptPassword(String password) {
// Simple encryption logic (for demonstration)
return password.replace("a", "@").replace("e", "3");
}
private String decryptPassword(String password) {
// Simple decryption logic
return password.replace("@", "a").replace("3", "e");
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
public class SerializeExample {
public static void main(String[] args) {
User user = new User("john_doe", "myp@ssw0rd");
// Serialization
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.dat"))) {
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.dat"))) {
User deserializedUser = (User) ois.readObject();
System.out.println(deserializedUser);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
How do I avoid rehashing overhead with std::set in multithreaded code?
How do I find elements with custom comparators with std::set for embedded targets?
How do I erase elements while iterating with std::set for embedded targets?
How do I provide stable iteration order with std::unordered_map for large datasets?
How do I reserve capacity ahead of time with std::unordered_map for large datasets?
How do I erase elements while iterating with std::unordered_map in multithreaded code?
How do I provide stable iteration order with std::map for embedded targets?
How do I provide stable iteration order with std::map in multithreaded code?
How do I avoid rehashing overhead with std::map in performance-sensitive code?
How do I merge two containers efficiently with std::map for embedded targets?