Java中的延迟引用设置

发布于 2024-08-20 12:52:53 字数 328 浏览 3 评论 0原文

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

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

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

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

我怎样才能在Java中实现这种延迟的引用设置?

I am developping a CORBA like inter object protocol that would support object aggregate transmission.

When objects of an aggregate are serialized, they may have references to objets serialized later. These are forward references. A simple example is a circular list. If each object has a reference to the previously serialized object, the first object will have a reference to the last serialized object to close the loop.

When deserializing and instantiating an object containing such a forward reference, its value is not known. It is only when the corresponding object is deserialized and instantiated that the reference value is known and could be set.

In C or C++ I use the reference (pointer) itself to hold the list of references to the same object to set when it is instantiated. In Java this is not possible.

How could I implement such delayed reference setting in Java ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

彻夜缠绵 2024-08-27 12:52:53

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

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

    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 

If the objects are immutable, then you build a temporary structure which will create them in an appropriate order ( obviously, this doesn't apply to circular lists, unless you use the setting final field reflective serialisation support ).

If not, either record the actions needed in an external list later, or use an interface with a resolve method for each member:
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 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文