Задержка ссылки в Java - PullRequest
       14

Задержка ссылки в Java

2 голосов
/ 05 февраля 2010

Я разрабатываю CORBA-подобный межобъектный протокол, который будет поддерживать агрегированную передачу объектов.

Когда объекты агрегата сериализуются, они могут иметь ссылки на объекты, сериализованные позже. Это прямые ссылки. Простой пример - круговой список. Если у каждого объекта есть ссылка на ранее сериализованный объект, первый объект будет иметь ссылку на последний сериализованный объект, чтобы закрыть цикл.

При десериализации и создании экземпляра объекта, содержащего такую ​​прямую ссылку, его значение неизвестно. Только когда соответствующий объект десериализован и создан, эталонное значение известно и может быть установлено.

В C или C ++ я использую саму ссылку (указатель) для хранения списка ссылок на один и тот же объект, который устанавливается при его создании. В Java это невозможно.

Как я могу реализовать такую ​​настройку отсроченных ссылок в Java?

1 Ответ

1 голос
/ 05 февраля 2010

Если объекты являются неизменяемыми, то вы создаете временную структуру, которая будет создавать их в соответствующем порядке (очевидно, это не относится к круговым спискам, если вы не используете установку окончательной поддержки отражающей сериализации поля).

Если нет, либо запишите действия, необходимые во внешнем списке, позже, либо используйте интерфейс с методом разрешения для каждого члена: открытый интерфейс IBar { IBar resol ();

    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 
...