如何使用ObjectInputStream将已存在的Singleton对象替换为已保存文件中的一个?

时间:2011-12-08 20:42:24

标签: java singleton ioexception objectinputstream

我正在创建一个具有基本保存/打开功能的Java应用程序。我需要保存的是我的类 ModeleImage 的实例,它是一个Singleton。我的保存显然有效,看起来像这样:

ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
outputStream.writeObject(ModeleImage.getInstance());
outputStream.flush();
outputStream.close();

现在我正在尝试使用ObjectInputStream打开该文件。我不确定是否有办法简单地用保存的单个替换我的Singleton(ModeleImage),但是现在我只是试图复制和替换每个属性。我的开场看起来像这样:

FileInputStream fis = new FileInputStream(fileChooser.getSelectedFile());
ObjectInputStream ois = new ObjectInputStream(fis);

//Get each attribute from the file and set them in my existing ModeleImage Singleton

ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage());
ModeleImage.getInstance().setLargeurImage(((ModeleImage) ois.readObject()).getLargeurImage());
ModeleImage.getInstance().setHauteurImage(((ModeleImage) ois.readObject()).getHauteurImage());
ModeleImage.getInstance().setxImage(((ModeleImage) ois.readObject()).getxImage());
ModeleImage.getInstance().setyImage(((ModeleImage) ois.readObject()).getyImage());

我也把try / catch放在各处。问题是我的开始部分在尝试替换属性时捕获了IOException。

ModeleImage.getInstance().setImage(((ModeleImage) ois.readObject()).getImage());
//This catches an IOException

我做错了什么? 是因为它是Singleton还是我误解了ObjectInputStream和readObject()是如何工作的?

4 个答案:

答案 0 :(得分:1)

通过使用序列化机制的内置功能,您可以通过在类文件中提供两个方法来增强正常过程。那些方法是:

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

通过ModeleImage类实现此方法,您将控制序列化的所有方面,并且可以访问单例的内部状态。

答案 1 :(得分:0)

你应该只调用readObject()一次,因为你只写了一个对象:

ModeleImage image = ois.readObject();
ModeleImage.getInstance().setImage((image.getImage());
ModeleImage.getInstance().setLargeurImage(image.getLargeurImage());
ModeleImage.getInstance().setHauteurImage((image.getHauteurImage());
ModeleImage.getInstance().setxImage(image.getxImage());
ModeleImage.getInstance().setyImage(image.getyImage());

答案 2 :(得分:0)

你应该做的是有一个静态块来检查你序列化的类的实例。如果可以找到它,它会将它设置为您的单例实例(从而确保从文件中加载一个实例)。如果它找不到它(也许是第一次启动你的程序),那么它应该创建一个实例并将它分配给你的单例变量。

您可以创建一个保存方法或不创建保存方法,或覆盖finalize方法以保存您的单例,以便下次在类加载时可以在静态块中检查它。

有意义吗?

答案 3 :(得分:0)

在可序列化的Singleton类上实现readResolve以确保只有一个实例并覆盖那里的属性,即

private Object readResolve() throws ObjectStreamException
{
    instance.setImage(getImage());
    instance.setLargeurImage(getLargeurImage());
    ... 
    return instance;
}

http://www.javalobby.org/java/forums/t17491.html上很好地描述了这个概念,或者在readResolve()上查看http://docs.oracle.com/javase/1.3/docs/guide/serialization/spec/input.doc6.html以获取更多信息。希望有所帮助。