serialization/deserialization mechanism

后端 未结 5 856
粉色の甜心
粉色の甜心 2021-01-13 04:42

Say, I have a class X which has a field value, that is,

class X implements Serializable {
    private i         


        
相关标签:
5条回答
  • The real details can be read in the Java Object Serialization Specification.

    To answer your questions:

    1. Serialization has a basic sanity check to see if the serialization ends use the same version of a class: the serialVersionUID member must be equal. Read the section Stream Unique Identifiers to know more about it. Basically, it's a static value which you can either manage yourself by declaring it on your class, or let the compiler generate one for you. If the compiler generates it, ANY change to a class will result in a change of serialVersionUID and hence will make the deserialization fail if the ends do not have exactly the same classes. If you want to avoid this, declare the variable yourself and update it manually when a change to the class' member variables does make classes incompatible.

    2. The Java Virtual Machine does a lot of the magic here, it can access all internal state directly without the need for getters (fields marked transient or static aren't serialized though). Also, while the Serializable interface doesn't specify any methods to implement, there are a number of 'magic methods' which you can declare to influence the serialization process. Read section "The writeObject Method" and onwards to know more. Be aware though that you should use these sparingly as they might confuse any maintenance developers!

    0 讨论(0)
  • 2021-01-13 05:24

    You don't need to have getters/setter to serialize/deserialize using java serialization, for example, check this code:

    public class Main {
    
        public static class Q implements Serializable {
            private int x;
            public Q() {
                x = 10;
            }
            public void printValue() {
                System.out.println(x);
            }
        }
    
        public static void main(String[] args) throws Exception {
            Q q = new Q();
            FileOutputStream fos = new FileOutputStream("c:\\temp.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(q);
            fos.close();
    
            FileInputStream fis = new FileInputStream("c:\\temp.out");
            ObjectInputStream oin = new ObjectInputStream(fis);
            Q q2 = (Q)oin.readObject();
            fis.close();
            q2.printValue();
    
        }
    }
    
    0 讨论(0)
  • 2021-01-13 05:30

    Some good links The Java serialization algorithm revealed

    1) does deserialization fail in case the access specifier of the field changes OR some or all of the methods go missing in the class at the deserialization end ?

    Serialization happens using Using Reflection

    Java Detects the changes to a class using the

    private static final long serialVersionUID

    The default involves a hashcode. Serialization creates a single hashcode, of type long, from the following information:

    • The class name and modifiers

    • The names of any interfaces the class implements

    • Descriptions of all methods and constructors except private methods and constructors

    • Descriptions of all fields except private, static, and private transient

    The default behavior for the serialization mechanism is a classic "better safe than sorry" strategy. The serialization mechanism uses the suid, which defaults to an extremely sensitive index, to tell when a class has changed. If so, the serialization mechanism refuses to create instances of the new class using data that was serialized with the old classes.

    2) what is the mechanism by which fields are assigned their values during deserialization ?

    0 讨论(0)
  • 2021-01-13 05:33

    Does deserialization fail in case the access specifier of the field changes

    No.

    OR some or all of the methods go missing in the class at the deserialization end?

    Yes, unless the receiving class has a serialVersionUID member whose value equals the value encoded in the stream.

    what is the mechanism by which fields are assigned their values during deserialization?

    Too broad, but:

    • Reflection, and
    • name matching (rather than matching by position in the class and stream).
    0 讨论(0)
  • 2021-01-13 05:37

    I don't really know how you get this results, but what you tell is not the default behaviour of serialisation. So, I guess you are using it wrong. Here is some sample code:

    public class X implements Serializable
    {
         private int value;
    
         public int getValue() { return value; }
    }
    

    Here the serialisation/deserialisation process:

    X x = new X();
    x.setValue(4);
    
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputSteam(buffer);
    oos.writeObject(x);
    oos.flush();
    oos.close();
    
    ByteArrayInputStream in = new ByteArrayInputStream(buffer.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(in);
    Object obj = ois.readObject();
    if (obj instanceof X)
    {
        X readObject = (X) obj;
        System.out.println(readObject.getValue());
    }
    

    You probably used Java Reflection to get your results. Make sure you use getDeclaredFields(); and getDeclaredMethods(); instead of the variants without Declared in the method name.

    0 讨论(0)
提交回复
热议问题