繁体   English   中英

Java序列化扩展类

[英]Java serialization extension of class

假设我有一类Article

public class Article implements Serializable
{
   private static final long serialVersionUID = 1420672609912364060L;
   private String title;
   private String text;
   private UUID uid;

   public Article(){ //empty default constructor
   }

   // Getters and setters 
   ...  
}

我使用以下代码序列化了它的多个实例

public void save(Article article)
{
    FileOutputStream fos = null;
    try {
        fos = context.openFileOutput("article_"+ article.getUid(), Context.MODE_PRIVATE);
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(article);
        os.close();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

然后,我稍后扩展该类,使其看起来像这样:

public class Article implements Serializable
{
   private static final long serialVersionUID = 1420672609912364060L;
   private String title;
   private String text;
   private Person author;
   private UUID uid;

   public Article(){
       author = Person.UNKNOWN;
   }

   // Getters and setters 
   ...
}

然后,当我加载它时,为什么作者为null? 我一直以为会调用默认构造函数,然后是每个找到的属性的设置器,但是在默认构造函数中放置一个断点,然后进行调试表明未调用它。 这意味着对于旧的Article类,作者将只是null而不是Person.UNKNOWN。 Person类本身也可以序列化。

如果可能的话,这是我在代码中的加载。

private Article loadArticle(String fileName)
{
    FileInputStream fis = null;
    try {
        fis = context.openFileInput(fileName);
        ObjectInputStream is = new ObjectInputStream(fis);
        Article article = (Article ) is.readObject();
        is.close();
        fis.close();
        return article;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (InvalidClassException e) {
    }
    catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}

请注意,所有配置均为Android

我一直以为默认的构造函数被称为

不,不是。 看一下文档

反序列化期间,将使用该类的公共或受保护的无参数构造函数初始化不可序列化类的字段。 无参数构造函数必须可序列化的子类可访问。 可序列化子类的字段将从流中恢复。

不,默认的构造函数没有被调用-它只是将序列化数据中未找到的每个字段都设置为0。

您可以像这样手动设置反序列化的自定义字段:

public class Article implements Serializable {
   private static final long serialVersionUID = 1420672609912364060L;
   private String title;
   private String text;
   private transient Person author;
   private UUID uid;

   public Article(){
       author = Person.UNKNOWN;
   }

   /**
    * Called upon deserialisation
    */
   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
       // read non transient fields
       in.defaultReadObject();
       author = Person.UNKNOWN;
   }

   // Getters and setters 
   ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM