您好我无法理解以下代码在序列化下的行为方式。
Foo被创建为临时对象,最终被用在Bar的匿名后代的方法中。 Bar是一个字段,并且在创建Foo对象的方法中幸存。
如何存储Foo对象。它是一个隐含的领域"酒吧对象?它是一个隐含的领域"程序对象?只是在Bar :: doSomething实现的代码中引用时,它是否仅在Heap上浮动?
我假设垃圾收集器足够智能,不会删除此对象。但序列化和反序列化后的Bar对象是否仍然指向同一个对象? Foo不可序列化,因此无法自行序列化。
对于那些想知道的人来说,样本来自我写的Wicket应用程序,而Foo和Bar就是我的模型。因此,Foo也是可序列化的,但是当Foo不可序列化时,这个问题似乎更有趣。
class Foo {
public void doSomethingElse() {
}
}
abstract class Bar implements Serializable {
public abstract void doSomething();
}
class Program {
Bar bar;
void main(String[] args) {
otherMethod(new Foo());
}
void otherMethod(Foo foo) {
bar = new Bar() {
@Override
public void doSomething() {
foo.doSomethingElse();
}
};
}
// much later after bar has been serialized and deserialized
void calledMuchLater() {
bar.doSomething();
}
}
答案 0 :(得分:1)
这里你实际上有两个问题。第一个是您正在创建的Bar类的实例是Program的内部类,而Program不是可序列化的。如果您尝试序列化匿名内部类,即使不担心Foo,也会出现错误。
当您创建匿名内部类时,类的代码中引用的任何变量都将通过Java透明生成的构造函数复制到类中。这些变量成为该类的实例字段,因此必须可序列化才能序列化该类。
答案 1 :(得分:0)
如果Foo
不是可序列化,则无效。你会得到java.io.NotSerializableException
。
如果Foo
是可序列化的,那么它将与Bar
一起序列化并成功反序列化。
如何存储Foo对象?它是一个隐含的领域"吧对象?
不确定如何,我认为无所谓。重要的是它被存储(iff Foo
是可序列化的;否则你得到一个例外,如上所述)。
只是在Bar :: doSomething实现的代码中引用时,它是否仅在Heap上浮动?
它不会浮动,它会在堆上放置。只要存在对此对象的实时引用,垃圾收集器就不会接收它。由于foo.doSomethingElse()
引用堆上的真实foo对象,它将保留在那里(实际上,这是创建内存泄漏的方法之一)。
但是,序列化和反序列化后的Bar对象是否仍然指向同一个对象?
没有。将创建类型为Bar
的新对象,从而还原序列化对象的状态。