First, you are not writing nothing when you write null
. You are writing a null value. The serialization process must make sure that when you will deserialize, you will get a null
back, so it must be represented in some way. There may also be overhead at the beginning to mark the start of the stream.
When you write "A", also, you are not just putting the "A" character. You are serializing a complete String object. This must contains information for the deserializer to rebuild a String object with the same value later. So there is type information, and the content. The content itself will also take more than one byte, because Java represents internally String as an array of char
, which are 2-bytes values, and also because the length of the string must be encoded in some way (actually I'm even surprised they'd put all that in just 8 bytes).
Edit: I have taken a look at the explanations on this page. We can use that to understand the results you obtain.
In the first example, you have the following bytes:
- AC ED (that's the hexadecimalese for -84 -19): STREAM_MAGIC. A magic value who specifies that this is a serialization protocol.
- 00 05 : STREAM_VERSION. The version 5.
- 70 (hexadecimal for 112): TC_NULL, represents a null value.
In your second example, actually the values you gave do not correspond. I have tried your code myself and I obtain that:
- AC ED : STREAM_MAGIC
- 00 05 : STREAM_VERSION
- 74 : TC_STRING, represents a new String
- 00 01: the length of the string (1)
- 65: the UTF8 representation of "A".
For the last byte, I was apparently a bit wrong: even if Java uses internally a 2-bytes representation for a char, it encodes String with UTF8, which uses only one byte for the character "A".
All the special values in the format are constants in the class ObjectStreamConstants