final transient fields and serialization

后端 未结 5 1820
无人及你
无人及你 2020-12-13 03:46

Is it possible to have final transient fields that are set to any non-default value after serialization in Java? My usecase is a cache variable — that\'s why i

5条回答
  •  时光取名叫无心
    2020-12-13 04:00

    Yes, this is easily possible by implementing the (apparently little known!) readResolve() method. It lets you replace the object after it is deserialized. You can use that to invoke a constructor that will initialize a replacement object however you want. An example:

    import java.io.*;
    import java.util.*;
    
    public class test {
        public static void main(String[] args) throws Exception {
            X x = new X();
            x.name = "This data will be serialized";
            x.cache.put("This data", "is transient");
            System.out.println("Before: " + x + " '" + x.name + "' " + x.cache);
    
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            new ObjectOutputStream(buffer).writeObject(x);
            x = (X)new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray())).readObject();
            System.out.println("After: " + x + " '" + x.name + "' " + x.cache);
        }
    
        public static class X implements Serializable {
            public final transient Map cache = new HashMap<>();
            public String name;
    
            public X() {} // normal constructor
    
            private X(X x) { // constructor for deserialization
                // copy the non-transient fields
                this.name = x.name;
            }
    
            private Object readResolve() {
                // create a new object from the deserialized one
                return new X(this);
            }
        }
    }
    

    Output -- the string is preserved but the transient map is reset to an empty (but non-null!) map:

    Before: test$X@172e0cc 'This data will be serialized' {This data=is transient}
    After: test$X@490662 'This data will be serialized' {}
    

提交回复
热议问题