A class object is represented by:
Arrays are represented by:
writeObject
/readObject
methods, there may be
optional objects and/or block-data records of primitive types written by
the writeObject
method followed by an endBlockData code.
writeObject
method or written directly to the stream from outside a writeObject
method.
This data may only be read by the corresponding readObject
methods or
directly from the stream. Objects written by writeObject
terminate any
previous block-data record and are written as regular objects, or null or back
references as appropriate. The block-data records allow error recovery to
discard any optional data. When called from within a class, the stream can
discard any data or objects until the endBlockData.
The table below contains the grammar. Nonterminal symbols are shown in italics. Terminal symbols in a fixed width font. Definitions of nonterminals are followed by a ":". The definition is followed by one or more alternatives, each on a separate line. The following table describes the notation:
Notation | Meaning |
---|---|
(datatype) | This token has the data type specified, such as byte. |
token[n] | A predefined number of occurrences of the token, that is an array. |
x0001 | A literal value expressed in hexadecimal. The number of hex digits reflects the size of the value. |
<xxx> | A value read from the stream used to indicate the length of an array. |
stream:
magic version contents
contents:
content
contents content
content:
object
blockdata
object:
newObject
newClass
newArray
newString
newClassDesc
prevObject
nullReference
exception
TC_RESET
newClass:
TC_CLASS classDesc newHandle
classDesc:
newClassDesc
nullReference
(ClassDesc)prevObject // an object required to be of type ClassDesc
superClassDesc:
classDesc
newClassDesc:
TC_CLASSDESC className serialVersionUID newHandle classDescInfo
classDescInfo:
classDescFlags fields classAnnotation superClassDesc
className:
(utf)
serialVersionUID:
(long)
classDescFlags:
(byte) // Defined in Terminal Symbols and Constants
fields:
(short)<count> fieldDesc[count]
fieldDesc:
primitiveDesc
objectDesc
primitiveDesc:
prim_typecode fieldName
objectDesc:
obj_typecode fieldName className
fieldName:
(utf)
className:
(String)object // String containing the field's type
classAnnotation:
endBlockData
contents endBlockData // contents written by annotateClass
prim_typecode:
`B' // byte
`C' // char
`D' // double
`F' // float
`I' // integer
`J' // long
`S' // short
`Z' // boolean
obj_typecode:
`[` // array
`L' // object
newArray:
TC_ARRAY classDesc newHandle (int)<size> values[size]
newObject:
TC_OBJECT classDesc newHandle classdata[] // data for each class
classdata:
nowrclass // SC_WRRD_METHOD & !classDescFlags
wrclass objectAnnotation // SC_WRRD_METHOD & classDescFlags
nowrclass:
values // fields in order of class descriptor
wrclass:
nowrclass
objectAnnotation:
endBlockData
contents endBlockData // contents written by writeObject
blockdata:
TC_BLOCKDATA (byte)<size> (byte)[size]
blockdatalong:
TC_BLOCKDATALONG (int)<size> (byte)[size]
endBlockData :
TC_ENDBLOCKDATA
newString:
TC_STRING newHandle (utf)
prevObject :
TC_REFERENCE (int)handle
nullReference :
TC_NULL
exception:
TC_EXCEPTION reset (Throwable)object reset
resetContext:
TC_RESET
magic:
STREAM_MAGIC
version :
STREAM_VERSION
values: // The size and types are described by the
// classDesc for the current object
newHandle: // The next number in sequence is assigned
// to the object being serialized or deserialized
final static short STREAM_MAGIC = (short)0xaced;
final static short STREAM_VERSION = 5;
final static byte TC_NULL = (byte)0x70;
final static byte TC_REFERENCE = (byte)0x71;
final static byte TC_CLASSDESC = (byte)0x72;
final static byte TC_OBJECT = (byte)0x73;
final static byte TC_STRING = (byte)0x74;
final static byte TC_ARRAY = (byte)0x75;
final static byte TC_CLASS = (byte)0x76;
final static byte TC_BLOCKDATA = (byte)0x77;
final static byte TC_ENDBLOCKDATA = (byte)0x78;
final static byte TC_RESET = (byte)0x79;
final static byte TC_BLOCKDATALONG = (byte)0x7A;
final static byte TC_EXCEPTION = (byte)0x7B;
final static byte SC_WRITE_METHOD = 0x01;
final static byte SC_SERIALIZABLE = 0x02;
final static byte SC_EXTERNALIZABLE = 0x04;
The flag SC_SERIALIZABLE is set if the class that wrote the stream extended
java.io.Serializable
but not java.io.Externalizable, the class reading the
stream must also extend Serializable and the default serialization mechanism is
to be used.
The flag SC_EXTERNALIZABLE is set if the class that wrote the stream
extended java.io.Externalizable
, the class reading the data must also
extend Externalizable and the data will be read using it's writeExternal and
readExternal methods.
class List implements java.io.Serializable {
int value;
List next;
public static void main(String[] args) {
try {
List list1 = new List();
List list2 = new List();
list1.value = 17;
list1.next = list2;
list2.value = 19;
list2.next = null;
ByteArrayOutputStream o = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(o);
out.writeObject(list1);
out.writeObject(list2);
out.flush();
...
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
00: ac ed 00 05 73 72 00 04 4c 69 73 74 69 c8 8a 15 >....sr..Listi...<
10: 40 16 ae 68 02 00 02 49 00 05 76 61 6c 75 65 4c >Z......I..valueL<
20: 00 04 6e 65 78 74 74 00 06 4c 4c 69 73 74 3b 78 >..nextt..LList;x<
30: 70 00 00 00 11 73 71 00 7e 00 00 00 00 00 13 70 >p....sq.~......p<
40: 71 00 7e 00 03 >q.~..<