2013-02-20 84 views
3

我发现许多线程运行在stackoverflow.com使SingleTon对象可序列化。 也有专家提供了序列化Singleton对象的方法。
我们如何序列化单身?我想我们不能

在我看来,即使我们实现Serializable接口,我们也不能Serialize对象,因为SingleTon引用变量在同一个类中是静态的。
而序列化API说我们不能序列化或写入文件中的静态引用状态。
而且我们也不能保存瞬态变量的状态。
虽然序列化过程(实际写入过程)静态和瞬态变量被忽略。
如果我误解了,请提供宝贵意见。如果我误解了,有人可以帮助序列化与代码示例Singleton对象?

+1

你试过实现一个实现Serializable的Singleton吗? – Achrome 2013-02-20 13:05:16

回答

1

是的,静态引用不是seralized。这并不意味着您无法获取静态引用(单例实例)的值并选择序列化它。

+0

那么,在这种情况下,我们可以保存值,而不需要在singleton类中实现Serializable接口。因为每个复杂对象(例如单例类的对象)都以像Integer,Long,Double,String等原始类型包装器对象结束,所有这些都使用Serializable接口实现,因此我们可以在单例对象内序列化值。我从你的评论中了解到,我们不能将Singleton作为一个对象序列化。相反,我们必须从中检索值并将其序列化到文件 – AmitG 2013-02-20 13:18:22

+0

@AmitG - 否,那不是我所说的。你当然可以序列化一个单身作为一个对象。 – jtahlborn 2013-02-20 14:41:06

2

我认为你正在混合实现单例的方式和对象序列化的方式。

虽然通常用于实现单例的静态字段实际上不会作为序列化实例的一部分被序列化,但实例本身可以绝对被序列化。您只需将其反序列化版本设置回静态字段,您需要在代码中手动执行该字段。

P.S.请注意,我并不是说序列化(甚至是实现)单例是一个好主意,我只是说它可以完成。

1

单身人士可以被序列化,在这里是如何做到这一点的代码:


import java.io.Serializable; 

public class MySingleton implements Serializable { 

    private MySingleton(String name) { 
     this.name = name; 
    } 

    private static MySingleton mySingleton; 

    private String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public static MySingleton getInstance(String name) { 
     if(mySingleton == null) { 
      System.out.println("in if..."); 
      mySingleton = new MySingleton(name); 
     } 

     return mySingleton; 
    } 
} 

,这里是“主”方法,获取Singleton类的实例之上,序列化和反序列化它:



public static void main (String[] args) { 

     MySingleton m = MySingleton.getInstance("Akshay"); 

     try { 
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D://temp.ser")); 
      oos.writeObject(m); 

      ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D://temp.ser")); 
      MySingleton m2 = (MySingleton) ois.readObject(); 
      System.out.println(m2.getName()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

    } 

和输出是: -

在如果...

Akshay

谢谢。

+2

但是,如果您比较sel化前后物体的哈希码,它们是不同的。意味着为Singleton类创建两个新实例!为了避免在你的Singleton类中使用readResolve方法,如下所示:'protected Object readResolve(){return 0;}} }' – 2014-04-29 07:50:05

+0

请参阅下面的链接以了解更多关于readResolve方法的信息:http://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html#5903 – 2014-04-29 07:57:11