序列化和反序列化是Java(以及通常的编程)中涉及将对象转换为字节流,以及反之的过程。当你需要传输或存储对象的状态时特别有用,比如将其通过网络发送或持久化到文件中。
序列化:
反序列化:
用途和实时应用:
网络通讯:
用例:当需要通过网络在不同应用程序或系统之间发送对象时。
示例:客户端-服务器应用程序,其中对象在客户端和服务器之间发送。
import java.io.*;
import java.net.*;
public class User implements Serializable {
private String username;
private transient String password; // Transient fields are not serialized
// Constructors, getters, setters...
public static void main(String[] args) {
// Serialization (Client Side)
try (Socket socket = new Socket("server_address", 12345);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream())) {
User user = new User("john_doe", "password123");
out.writeObject(user);
System.out.println("User object sent to server");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization (Server Side)
try (ServerSocket serverSocket = new ServerSocket(12345);
Socket clientSocket = serverSocket.accept();
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream())) {
User receivedUser = (User) in.readObject();
System.out.println("Received User object: " + receivedUser);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
持久化:
import java.io.*;
public class UserPreferences implements Serializable {
private String theme;
private int fontSize;
// Constructors, getters, setters...
public static void main(String[] args) {
// Serialization (Save Preferences)
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user_preferences.ser"))) {
UserPreferences preferences = new UserPreferences("dark", 16);
out.writeObject(preferences);
System.out.println("User preferences saved to file");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization (Load Preferences)
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("user_preferences.ser"))) {
UserPreferences loadedPreferences = (UserPreferences) in.readObject();
System.out.println("Loaded User preferences: " + loadedPreferences);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
缓存:
import java.io.*;
import java.util.HashMap;
import java.util.Map;
public class CacheManager implements Serializable {
private Map<String, Object> cache = new HashMap<>();
// Methods to put, get, and manage the cache...
public static void main(String[] args) {
// Serialization (Save Cache)
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.ser"))) {
CacheManager cacheManager = new CacheManager();
cacheManager.put("queryResult1", /* database query result */);
cacheManager.put("queryResult2", /* another query result */);
out.writeObject(cacheManager);
System.out.println("Cache saved to file");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization (Load Cache)
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.ser"))) {
CacheManager loadedCacheManager = (CacheManager) in.readObject();
System.out.println("Loaded Cache: " + loadedCacheManager);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
消息队列:
import java.io.*;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
public class MessageQueue implements Serializable {
private Queue<String> messages = new ArrayBlockingQueue<>(10);
// Methods to add, retrieve, and manage messages...
public static void main(String[] args) {
// Serialization (Save Message Queue)
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("message_queue.ser"))) {
MessageQueue messageQueue = new MessageQueue();
messageQueue.addMessage("Message1");
messageQueue.addMessage("Message2");
out.writeObject(messageQueue);
System.out.println("Message Queue saved to file");
} catch (IOException e) {
e.printStackTrace();
}
// Deserialization (Load Message Queue)
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("message_queue.ser"))) {
MessageQueue loadedMessageQueue = (MessageQueue) in.readObject();
System.out.println("Loaded Message Queue: " + loadedMessageQueue);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
远程方法调用(RMI):
import java.rmi.*;
import java.rmi.registry.*;
public interface RemoteCalculator extends Remote {
int add(int a, int b) throws RemoteException;
// Other remote methods...
}
public class CalculatorImpl implements RemoteCalculator {
public int add(int a, int b) throws RemoteException {
return a + b;
}
// Other method implementations...
}
public class RmiServer {
public static void main(String[] args) {
try {
RemoteCalculator calculator = new CalculatorImpl();
Registry registry = LocateRegistry.createRegistry(1099);
Naming.rebind("CalculatorService", calculator);
System.out.println("RMI Server is running...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class RmiClient {
public static void main(String[] args) {
try {
RemoteCalculator calculator = (RemoteCalculator) Naming.lookup("rmi://localhost/CalculatorService");
int result = calculator.add(5, 10);
System.out.println("Result from RMI server: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
总之,在Java中,序列化涉及将对象转换为字节流,从而实现其存储或传输;而反序列化则从字节流重构原始对象。这些过程对于诸如将对象状态保存到文件、通过网络发送对象或将数据持久化到数据库等任务至关重要,确保数据能够轻松存储、传输和随后重建。