这是我使用可序列化接口(interface)的部分。当我启动程序时,它将为每个列表创建相同的对象,但具有不同的引用。有什么办法可以将它们全部作为一个引用吗?
private static void quitApplication(){
System.out.println("Stopping the system...\n");
///store all the objects by serializing
try {
FileOutputStream fileOut2 = new FileOutputStream("FlightList.ser");
ObjectOutputStream out2 = new ObjectOutputStream(fileOut2);
out2.writeObject(Flight.getFlights());
out2.close();
fileOut2.close();
}catch(IOException i) {
System.out.println("FlightList.ser ERROR");
}
try {
FileOutputStream fileOut = new FileOutputStream("CityList.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(City.getCityList());
out.close();
fileOut.close();
}catch(IOException i) {
System.out.println("CityList.ser ERROR");
}
try {
FileOutputStream fileOut1 = new FileOutputStream("GrapghL.ser");
ObjectOutputStream out1 = new ObjectOutputStream(fileOut1);
out1.writeObject(Test.flightGraph);
out1.close();
fileOut1.close();
}catch(IOException i) {
System.out.println("GrapghL.ser ERROR");
}
System.out.println("Done...Thank You For using the Airlines System");
}
private static void initializeData(){
try {
FileInputStream fileIn = new FileInputStream("CityList.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
City.setCityList((MyList<City>) in.readObject());
in.close();
fileIn.close();
}catch(Exception i){
System.out.println("CityList.ser ERROR");
}
try {
FileInputStream fileIn2 = new FileInputStream("FlightList.ser");
ObjectInputStream in2 = new ObjectInputStream(fileIn2);
Flight.setFlights((MyList<Flight>) in2.readObject());
in2.close();
fileIn2.close();
}catch(Exception i){
System.out.println("FlightList.ser ERROR");
}
try {
FileInputStream fileIn1 = new FileInputStream("GrapghL.ser");
ObjectInputStream in1 = new ObjectInputStream(fileIn1);
Test.flightGraph = (DefaultDirectedWeightedGraph<City, DefaultWeightedEdge>) in1.readObject();
in1.close();
fileIn1.close();
}catch(Exception i){
System.out.println("GrapghL.ser ERROR");
}
}
最佳答案
实际上有一个official Java-tutorial对此。正如 EJP 所提到的,您实现了 readResolve()。
我为 Java 1.6+ 重写了示例类:;-)
导入 java.io.ObjectStreamException; 导入 java.io.Serializable; 导入 java.util.HashMap; 导入 java.util.Map;
public class RememberMe implements Serializable {
/**
* Contains all known instances by id. If you feel the need to permanently discard an object you have to remove it from this Map.
*/
static final Map<Integer, RememberMe> knownInstances = new HashMap<Integer, RememberMe>();
/**
* There is always only one object by this id reachable
*/
private final int id;
/**
* A changeable field
*/
private String name;
/**
* Another changeable field
*/
private String location;
/**
* Private constructor so we can ship existing instances
*/
private RememberMe(final int id, final String name, final String location) {
this.id = id;
this.name = name;
this.location = location;
}
/**
* This is how you create and access objects of this class. name and location are ignored if an id already exists
*/
public static RememberMe getRememberMe(int id, String name, String location) {
synchronized (knownInstances) {
final RememberMe oldValue = knownInstances.get(id);
if(oldValue != null) {
return oldValue;
} else {
final RememberMe newValue = new RememberMe(id, name, location);
knownInstances.put(id, newValue);
return newValue;
}
}
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
/**
* This function is called after the Object is fully created (i.e. after constructor was called and all objects
* referenced by field have been created). Now we only need to decide if it is the first of it's kind or we already
* know an object by that id.
*/
private Object readReplace() throws ObjectStreamException {
synchronized (knownInstances) {
final RememberMe oldValue = knownInstances.get(id);
if(oldValue != null) {
return oldValue;
} else {
knownInstances.put(id, this);
return this;
}
}
}
}
这是如何运作的?
- 有一张 map 知道该类的所有实例
- 如果对象被反序列化,我们使用
readReplace()
将其替换为之前使用相同 ID 创建的任何实例。
您需要注意,在创建对象期间,对象不会在任何地方注册自己,因为这些引用不会被 readReplace()
更改;因此,该类在 getRememberMe
中的 knownInstances
中注册,而不是在构造函数中注册!
如果您希望能够让 GC 回收此类的对象,您可能需要用一些 Weak*-variant 替换 HashMap
或其值。
关于java - 如何在序列化中获得相同的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20654581/