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 instanti开发者_StackOverflow中文版ated 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 ?
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
精彩评论