Instructions for using transient keyword

In Java, the transient keyword is used to indicate that a field does not need to be serialized. For example, some sensitive information (mobile phone number, password, etc.) does not need to be serialized. It should be noted that the transient keyword can only modify variables, not methods or classes. Class variables (static variables, modified by the static keyword) cannot be serialized, so there is no need to add the transient keyword. Variables modified with final will not affect the effect of the transient keyword. In particular, if you implement serialization based on the Externalizable interface, you need to manually specify the properties that need to be serialized, so they are not affected by the transient keyword. In other words, objects serialized based on the Externalizable interface are not affected by the transient keyword. Next, verify the above conclusion through code.

Use the transient keyword to mark fields that do not require serialization

In Java, the transient keyword is used to indicate that a field does not need to be serialized. Note that the transient keyword can only mark a field that does not require serialization, and does not implement related capabilities. In actual applications, it was found that all three-party components will not serialize the fields marked with the transient keyword when serializing. Below are examples.

public void testTransientByFastJson() {<!-- -->
    //Based on fastjson 1.2.67 verification
    User user = new User();
    user.setUsername("foo");
    user.setPassword("123456789");
    System.out.println(JSON.toJSONString(user)); // Output: {"username":"foo"}
    User testUser = JSON.parseObject("{"username":"foo","password":"123456789"}", User.class);
    System.out.println(testUser.getPassword()); // Output: "123456789"
}

public void testTransientByStream() throws IOException, ClassNotFoundException {<!-- -->
    User user = new User();
    user.setUsername("foo");
    user.setPassword("123456789");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(user);
    oos.close();
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    User deserializedUser = (User) ois.readObject();
    ois.close();
    System.out.println(deserializedUser.getUsername()); // Output "foo"
    System.out.println(deserializedUser.getPassword()); // Outputs null because the password property is not serialized
}

The above code uses fastjson (Alibaba open source third-party software) and the stream processing tool class that comes with the JDK to implement serialization. You can see that the fields marked with the transient keyword will not be serialized into the results. At the same time, we also noticed that during deserialization, the fastjson third-party software will restore the fields marked by the transient keyword. In other words, different frameworks may have different recovery methods for deserialization of fields marked with the transient keyword, so they must be verified before use.

Class variables will not be serialized

Serialization and deserialization are for objects. Class variables (modified by the static keyword) are not the state of the object, so they will not be serialized. They are part of a class, not separate objects.

public class MyClass implements Serializable {<!-- -->
    private static MyClass myVariable; // This is a class variable
    //This is an instance variable
    private MyClass instanceVariable;

    // Constructor, getter, setter and other codes
}

In this example, myVariable is a class variable and instanceVariable is an instance variable. When objects of MyClass are serialized and deserialized, only instanceVariable will be serialized, but myVariable will not be serialized.

The variables repaired by final do not affect the effect of transient

In Java, the final keyword does not directly affect the serialization of objects. Serialization is the process of converting an object’s state information into a stream of bytes so that it can be stored to disk or sent over the network to another process running Java. The final keyword represents an immutable variable in Java. If an object is final, then it cannot be referenced by another object, which means it cannot be modified. However, even if an object is final, it can still be serialized and deserialized. In short, the final keyword itself does not directly affect the serialization process of the object.

//Define entities
public class User implements Serializable {<!-- -->
    // Use final to fix variables
    private final String code;
    private String username;
    private transient String password;
    public User() {<!-- -->
        this.code = "001";
    }

    public String getUsername() {<!-- -->
        return username;
    }

    public void setUsername(String username) {<!-- -->
        this.username = username;
    }

    public String getPassword() {<!-- -->
        return password;
    }

    public void setPassword(String password) {<!-- -->
        this.password = password;
    }

    public String getCode() {<!-- -->
        return code;
    }
}
// use entities
public class TransientDemo {<!-- -->
    public void testTransientByFastJson() {<!-- -->
        User user = new User();
        user.setUsername("foo");
        user.setPassword("123456789");
        User.setType("local");
        // {"code":"001","username":"foo"}
        System.out.println(JSON.toJSONString(user));
    }
}

It can be seen that the final keyword itself does not affect the serialization of objects, and variables modified with final can still be serialized.

Serialization implemented based on the Externalizable interface is not affected by transient

The Externalizable interface in Java is a way to customize object serialization. By implementing the Externalizable interface, you can control the serialization and deserialization process of an object, as well as which fields are written and read during serialization and deserialization. To implement the Externalizable interface, you need to implement two methods: writeExternal() and readExternal(). Among them, the writeExternal() method is used to write the fields of the object to the output stream, while the readExternal() method is used to read the fields from the input stream and set them into the object.

//Define the entity and implement the Externalizable interface
public class Person implements Externalizable {<!-- -->
    private transient String name;
    private int age;
    public Person(String name, int age) {<!-- -->
        this.name = name;
        this.age = age;
    }
    public String getName() {<!-- -->
        return this.name;
    }
    public int getAge() {<!-- -->
        return this.age;
    }
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {<!-- -->
        out.writeUTF(name);
        out.writeInt(age);
    }
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {<!-- -->
        name = in.readUTF();
        age = in.readInt();
    }
}
// use entities
public class TransientDemo {<!-- -->
    public void testExternalWithTransient() throws IOException, ClassNotFoundException {<!-- -->
        Person person = new Person("jack", 25);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(person);
        oos.close();
        System.out.println(bos.toByteArray());
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bis);
        Person deserializedPerson = (Person) ois.readObject();
        ois.close();
        System.out.println(deserializedPerson.getName()); // Output "jack", even if the field has been modified with the transient keyword, it will not affect serialization
        System.out.println(deserializedPerson.getAge()); // Output 25
    }
}

It should be noted that not all frameworks support the Externalizable interface method. Taking fastjson as an example, the deserialization result of the above Person instance is “{}”. When using it, be sure to verify it in advance to ensure that the Which serialization implementation is supported by the serialization framework.

Reference

https://zhuanlan.zhihu.com/p/362241118 Java keyword transient
https://blog.csdn.net/qq_44543508/article/details/103232007 Detailed explanation of the transient keyword in java
https://www.runoob.com/w3cnote/java-transient-keywords.html Java transient keywords
https://www.baidu.com/ Baidu AI search
https://www.cnblogs.com/lanxuezaipiao/p/3369962.html Notes on using the Java transient keyword