如何使用反序列化将我的对象恢复生机?

时间:2013-12-19 04:34:41

标签: java serialization deserialization

我将类对象序列化为这样的文件:

public class GreenhouseControls extends Controller implements Serializable {

    private static final long serialVersionUID = -7079669536704670179L;
    private long               numOfRings;
    private long               rings;
    private Event              event;
    private Scanner            s;
    private ArrayList<String>  array;
    private ArrayList<String>  array2;
    private ArrayList<String>  array3;
    public  boolean            windowok;
    public  boolean            poweron;
    public  boolean            fans;
    public  boolean            light;
    public  boolean            water;
    public  String             thermostat;
    private String             eventsFile;
    public  int                errorcode;
    private String             dumpFile;

    ......

    public void saveState() {
        try {
            // Serialize data object to a file
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("dump.out"));
            out.writeObject(GreenhouseControls.this);
            out.close();
        } catch (IOException e) { }
    }
     .....  
}

文件存在,如下所示:

Package Explorer Image  

现在我想反序列化该对象。这就是我到目前为止所做的:

public class Restore extends Event {

      public Restore(long delayTime, String dumpFile){
          super(delayTime);
          eventsFile = dumpFile;
      } 
      @Override
      public void action() throws ControllerException { 
          try {
              FileInputStream fis = new FileInputStream(eventsFile);
              ObjectInputStream ois = new ObjectInputStream(fis);  
              GreenhouseControls gc = (GreenhouseControls) ois.readObject(); // Error occurs here 

              ois.close();        
          }catch (IOException | ClassNotFoundException e) {
              e.printStackTrace();
          } 
      }
      public String toString() {
          return "Restoring system";
      }  
  }

上面的Restore类是否接近我对反序列化对象所需要做的事情? 当我运行我的程序时,我得到WriteAbortedException和NotSerializableException。

以下是例外情况:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.util.Scanner
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at greenhouse.GreenhouseControls$Restore.action(GreenhouseControls.java:374)
    at other.Controller.run(Controller.java:39)
    at greenhouse.GreenhouseControls.main(GreenhouseControls.java:530)
Caused by: java.io.NotSerializableException: java.util.Scanner
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at greenhouse.GreenhouseControls.saveState(GreenhouseControls.java:487)
    at other.Controller.run(Controller.java:43)
    at greenhouse.GreenhouseControls.main(GreenhouseControls.java:524)

这是我的Event类:

import java.io.Serializable;

import greenhouse.GreenhouseControls.ControllerException;

public abstract class Event implements Serializable{
  private long eventTime;
  protected final long delayTime;


  public Event(long delayTime) {
      this.delayTime = delayTime;
      start();
  }

  public void start() { // Allows restarting
    eventTime = System.currentTimeMillis() + delayTime;
  }

  public boolean ready() {
    return System.currentTimeMillis() >= eventTime;
  }

  public abstract void action() throws ControllerException;
 }

2 个答案:

答案 0 :(得分:3)

您无法序列化Scanner.或任何类型的输入或输出流,读取器,写入器,套接字,连接......使扫描仪瞬态化。更好的是,无论使用何种方法,它都是一个局部变量。你不可能在课堂上使用相同的Scanner,如果你是,我建议你做错了。

答案 1 :(得分:1)

序列化之前要记住一些要点,

  1. 如果该类被标记为Serializable,,则该类中包含的所有变量也应为Serializable
  2. 如果类包含一些无法序列化的对象,则对它们添加transient关键字。
  3. 在您的情况下,您应将Scanner变量声明为transient

    private transient Scanner s;
    

    其次,您的班级Event是否可序列化?即如果它是你自己的自定义类,它是否实现Serializable