As stated above, the declaration below does not work, as you might expect:
transient final Object foo = new Object()
The transient keyword will not allow member serialization. Initialization with the default value is not performed during deserialization , so foo will be null after deserialization.
The final keyword will prevent member modification after it is installed. This means that you are stuck with null forever in a deserialized instance.
In any case, you need to abandon the final keyword. This will sacrifice immutability, but usually this should not be a problem for private members.
Then you have two options:
Option 1: overriding readObject()
transient Object foo = new Object(); @Override private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); foo = new Object(); }
When creating a new instance, foo will be initialized by default. When deserializing, your custom readObject() method readObject() take care of that.
This will work on the JRE, but not on Android, as the readObject() method is missing in the Android Serializable implementation.
Option 2: Lazy Initialization
Declaration:
transient Object foo;
Available:
if (foo == null) foo = new Object(); doStuff(foo);
You will need to do this wherever you get access to foo in your code, which may be more difficult and more error prone than the first option, but it will work on both JRE and Android.
user149408 Jun 12 '16 at 15:54 2016-06-12 15:54
source share