在序列化时需要处理对象吗?

时间:2014-05-21 01:13:07

标签: java serialization

我是Java的新手,我想知道在序列化时是否有必要将对象释放到空闲内存中?我尝试在序列化后使用我的可序列化对象并且工作正常但我的目标是在获得它之前不能访问。感谢。

Poo p = new Poo();
try {
        FileOutputStream g = new FileOutputStream("obj.ser");
        ObjectOutputStream stream = new ObjectOutputStream(g);
        stream.writeObject(p);
        stream.close();
    }
catch(Exception e) { e.printStackTrace(); }
p.getInfo(); // works

3 个答案:

答案 0 :(得分:2)

您可以使用自定义序列化的方法使对象无效(即,在每次调用非私有方法时使对象抛出异常;这样至少可以确保没有成功调用任何方法。)

public final class Poo implements Serializable {
    private volatile boolean invalid = false;
    public String getInfo() {
         synchronized (this) {
             if (invalid) {
                 throw new IllegalStateException("Object shouldn't be used until deserialized");
             }
         }
         // do something
    }

    // do the same to other methods
    // if necessary Object methods like equals and hashCode too

    private class SerializationProxy implements Serializable {
        private Object readResolve() {
            Poo.this.invalid = false;
            return Poo.this;
        }
    }

    private synchronized Object writeReplace() {
        invalid = true;
        return new SerializationProxy();
    }
}

但是,如果您只想使内存可用,则只需将对象的所有引用设置为null即可。例如。如果没有对p的静态引用:

p = null;

在范围结束时自动完成的是您声明p(很可能是方法的结尾)。也许编译器甚至可以做一些优化(如果不再需要,则释放对象);但我不知道,如果语言规范允许这样做。

修改

制作Poo final以阻止继承的类覆盖&添加方法并忽略invalid字段。

答案 1 :(得分:1)

答案是,并不总是需要"处理"序列化后的对象。

如果您有特定原因"处理"对象(无论在代码的上下文中意味着什么),然后这样做。如果您对此具体原因有疑问,请改进您的问题,但您的问题在一般意义上会问,并且在这个意义上,答案是否定的。

答案 2 :(得分:1)

序列化是基于内存中的对象生成一些字节。您可以对这些字节执行某些操作,例如将它们写入文件,通过网络发送等等。原始对象保持不变。

将对象置于"释放内存"在程序不再可访问对象后的某个时间由垃圾收集器自动执行。您可以做的最好的事情是确保您没有对该对象进行任何引用。然后将收集它。

这些是独立且无关的概念。