Java中的延迟引用设置

Java中的延迟引用设置,java,object,reference,serialization,aggregate,Java,Object,Reference,Serialization,Aggregate,我正在开发一个类似CORBA的对象间协议,它将支持对象聚合传输 当对聚合对象进行序列化时,它们可能会在以后序列化对象。这些是前瞻性参考。一个简单的例子是循环列表。如果每个对象都有一个对先前序列化对象的引用,则第一个对象将有一个对最后一个序列化对象的引用以关闭循环 当反序列化和实例化包含此类正向引用的对象时,其值未知。只有当对应的对象被反序列化和实例化时,引用值才是已知的,并且可以设置 在C或C++中,我使用引用(指针)本身来保存在实例化时要设置的同一对象的引用列表。在Java中,这是不可能的 如

我正在开发一个类似CORBA的对象间协议,它将支持对象聚合传输

当对聚合对象进行序列化时,它们可能会在以后序列化对象。这些是前瞻性参考。一个简单的例子是循环列表。如果每个对象都有一个对先前序列化对象的引用,则第一个对象将有一个对最后一个序列化对象的引用以关闭循环

当反序列化和实例化包含此类正向引用的对象时,其值未知。只有当对应的对象被反序列化和实例化时,引用值才是已知的,并且可以设置

<>在C或C++中,我使用引用(指针)本身来保存在实例化时要设置的同一对象的引用列表。在Java中,这是不可能的


如何在Java中实现这种延迟引用设置?

如果对象是不可变的,那么您将构建一个临时结构,以适当的顺序创建它们(显然,这不适用于循环列表,除非您使用设置最终字段反射序列化支持)

如果没有,请稍后在外部列表中记录所需的操作,或者为每个成员使用带有解析方法的接口: 公共接口IBar{ IBar解析()

static IBar EMPTY=new IBar(){
公共IBar解析(){
抛出新的RuntimeException();
}
}
}
公共接口IFoo{
ifooresolve();
...
}
公共类Foo实现了IFoo{
专用IBar条=IBar.EMPTY;
公共Foo(IBar-bar){this.bar=bar;}
公共酒吧{
返回bar.resolve();
}
公共字符串getId(){…}
公共IFoo解析(){
bar=bar.resolve();
归还这个;
}
}
公共类加载器{
私有HashMap fooRefs=新建。。。
私有HashMap barRefs=新建。。。
专用IBar barRef(字符串id){
ifoofoo=fooRefs.get(id);
if(foo==null){
foo=新的ForwardFooRef(id);
fooRefs.put(id,foo);
}
返回foo;
}
已创建私有IFoo(IFoo-foo){
IFoo exant=fooRefs.get(foo.getId());
if(现存的!=null)
if(ForwardFoorRef的现有实例)
(ForwardFooRef)现存的.setReferent(foo);
其他的
抛出新的RuntimeException(“具有相同id的多个对象”);
返回foo;
}
公共空荷载(){
创建每个对象
使用created注册它
如果找到了ref,请使用地图进行查找
如果ref在地图中,请使用它
如果ref是forward,则它是使用temp创建的
遍历对象树解决任何问题

您的示例很有趣,因为它使用技巧存储对虚拟对象的引用,该虚拟对象包含解析转发引用所需的信息。此虚拟对象也可以包含侵入性链接。在我的系统中,所有可序列化类都继承自基类serializable,该基类可以具有解析转发引用的方法引用。实现可以遍历所有引用,如果它们引用一个伪可序列化对象,则使用其包含的信息来解析链接。是这样吗?无论如何,这很好。
    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