Java中的延迟参考设置
问题描述:
我正在开发支持对象聚合传输的CORBA类对象协议。Java中的延迟参考设置
当聚合对象序列化时,它们可能会引用稍后序列化的objets。这些是前瞻性参考。一个简单的例子是一个圆形列表。如果每个对象都有对先前序列化对象的引用,则第一个对象将引用最后一个序列化对象来关闭该循环。
当反序列化和实例化一个包含这样的前向引用的对象时,它的值是未知的。只有当对应的对象被反序列化和实例化时,参考值已知并且可以被设置。
在C或C++中,我使用引用(指针)本身来保存对实例化时设置的同一对象的引用列表。在Java中这是不可能的。
我该如何在Java中实现这样的延迟参考设置?
答
如果对象是不可改变的,那么你建立一个临时的结构将在适当的顺序(显然,这并不适用于圆名单,除非你使用的设置最终场反射序列化支持)创建它们。
如果不是,请稍后在外部列表中记录所需的操作,或者为每个成员使用具有解析方法的接口: public interface IBar IBar resolve();
static IBar EMPTY = new IBar() {
public IBar resolve() {
throw new RuntimeException();
}
}
}
public interface IFoo {
IFoo resolve ();
...
}
public class Foo implements IFoo {
private IBar bar = IBar.EMPTY;
public Foo (IBar bar) { this.bar = bar; }
public Bar getBar() {
return bar.resolve();
}
public String getId() { ... }
public IFoo resolve() {
bar = bar.resolve();
return this;
}
}
public class Loader {
private HashMap<String,IFoo> fooRefs = new ...
private HashMap<String,IBar> barRefs = new ...
private IBar barRef (String id) {
IFoo foo = fooRefs.get(id);
if (foo==null) {
foo = new ForwardFooRef(id);
fooRefs.put(id,foo);
}
return foo;
}
private IFoo created (IFoo foo) {
IFoo extant = fooRefs.get(foo.getId());
if (extant != null)
if (extant instanceof ForwardFooRef)
((ForwardFooRef)extant).setReferent(foo);
else
throw new RuntimeException("more than one object with the same id ");
return foo;
}
public void load() {
create each object
register it using created
if a ref is found, use the maps to look it up
if the ref is in teh map, use it
if ref is forward, it's created with a temp
walk object tree resolving anything
您的示例很有趣,因为它使用技巧来存储对保留解析前向引用所需信息的虚拟对象的引用。这个虚拟对象也可以容纳侵入链。 在我的系统中,所有可序列化的类继承自基类Serializable,它可以有一个方法来解析前向引用。该实现可以遍历所有引用,如果它们引用一个虚拟Serializable对象,则使用其包含的信息来解析该链接。 是这个想法吗?无论如何,这是非常好的。 – chmike 2010-02-05 15:08:49