Allow any Streamable class to use the "we'll call your single non-zero-argument
constructor with zero/null values and then overwrite any fields initialized with them immediately afterward" approach. If a Streamable has a zero-args constructor, that is still used, so all the existing Streamable classes will still function exactly as before. But new classes (or old classes undergoing scrutiny) can opt to reduce their boilerplate as long as they know they cope with the zero/null-valued constructor call. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6573 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -25,9 +25,9 @@ package com.threerings.io;
|
|||||||
* Marks an object as streamable, meaning that it can be written to {@link ObjectOutputStream}
|
* Marks an object as streamable, meaning that it can be written to {@link ObjectOutputStream}
|
||||||
* instances and read from {@link ObjectInputStream} instances.
|
* instances and read from {@link ObjectInputStream} instances.
|
||||||
*
|
*
|
||||||
* <p> All non-{@code transient} fields will be automatically written and restored for a {@link
|
* <p> All non-{@code transient}, non-{@link NotStreamable} fields will be automatically written
|
||||||
* Streamable} instance. Classes that wish to stream transient fields or customize the streaming
|
* and restored for a {@link Streamable} instance. Classes that wish to stream transient fields or
|
||||||
* process should implement methods with the following signatures: </p>
|
* customize the streaming process should implement methods with the following signatures: </p>
|
||||||
*
|
*
|
||||||
* <p><code>
|
* <p><code>
|
||||||
* public void writeObject ({@link ObjectOutputStream} out);
|
* public void writeObject ({@link ObjectOutputStream} out);
|
||||||
@@ -38,6 +38,14 @@ package com.threerings.io;
|
|||||||
* ObjectOutputStream#defaultWriteObject} and {@link ObjectInputStream#defaultReadObject} from
|
* ObjectOutputStream#defaultWriteObject} and {@link ObjectInputStream#defaultReadObject} from
|
||||||
* within their {@code writeObject} and {@code readObject} methods to perform the standard
|
* within their {@code writeObject} and {@code readObject} methods to perform the standard
|
||||||
* streaming in addition to their customized behavior.</p>
|
* streaming in addition to their customized behavior.</p>
|
||||||
|
*
|
||||||
|
* <p>Streamable classes must <em>either</em> have a zero-argument constructor, in which case any
|
||||||
|
* number of other constructors are allowed, but the zero-argument constructor will be used when
|
||||||
|
* unserializing an instance; or they must have exactly one non-zero-argument constructor, and that
|
||||||
|
* constructor will be called when unserializing an instance with "zero/null" values (meaning all
|
||||||
|
* primitive types will be passed the appropriate zero value, and all reference types will be
|
||||||
|
* passed null. This latter approach can even be used by classes with final fields, as the
|
||||||
|
* zero/null values will be overwritten during unstreaming.</p>
|
||||||
*/
|
*/
|
||||||
public interface Streamable
|
public interface Streamable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -421,9 +421,9 @@ public abstract class Streamer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're an anonymous closure, we also support having a single constructor to which
|
// otherwise there should be a single non-zero-argument constructor, which we'll call
|
||||||
// we'll pass zero-valued arguments, which will then be overwritten by unstreaming
|
// with zero-valued arguments at unstreaming time, which will then be overwritten by
|
||||||
if (Streamable.Closure.class.isAssignableFrom(_target) && _ctor == null) {
|
// readObject()
|
||||||
Constructor<?>[] ctors = _target.getDeclaredConstructors();
|
Constructor<?>[] ctors = _target.getDeclaredConstructors();
|
||||||
if (ctors.length > 1) {
|
if (ctors.length > 1) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
@@ -444,13 +444,6 @@ public abstract class Streamer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we found a constructor
|
|
||||||
if (_ctor == null) {
|
|
||||||
throw new RuntimeException("Unable to find applicable ctor " +
|
|
||||||
"[class=" + _target.getName() + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the reading and writing marshallers.
|
* Initialize the reading and writing marshallers.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user