Home  >  Article  >  Java  >  Summary of Java transient keyword usage

Summary of Java transient keyword usage

黄舟
黄舟Original
2017-02-23 10:22:251447browse

Hey, although I am most familiar with Java, I don’t know a lot of basic Java knowledge. For example, the transient keyword has never been used before, so I don’t know what its function is. I found a question when I was doing the written test today. It’s about this, so I spent some time sorting out the use of the transient keyword and got my bearings~~~Okay, without further ado, let’s start:

1. Transient Function and usage

We all know that as long as an object implements the Serilizable interface, the object can be serialized. This serialization mode of Java provides developers with a lot of conveniences. We don’t need to worry about the specific sequence. In the process of serialization, as long as this class implements the Serilizable interface, all properties and methods of this class will be automatically serialized.

However, in the actual development process, we often encounter such a problem. Some attributes of this class need to be serialized, while other attributes do not need to be serialized. For example, if a user has some sensitive Information (such as passwords, bank card numbers, etc.), for security reasons, is not expected to be transmitted during network operations (mainly involving serialization operations, local serialization cache is also applicable), the variables corresponding to this information can be added with the transient keyword . In other words, the life cycle of this field only exists in the caller's memory and will not be written to disk for persistence.

In short, the transient keyword of java provides us with convenience. You only need to implement the Serilizable interface and add the keyword transient before the properties that do not need to be serialized. When serializing the object, this property will not Serialized to the specified destination.

The sample code is as follows:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
 * @description 使用transient关键字不序列化某个变量
 *        注意读取的时候,读取数据的顺序一定要和存放数据的顺序保持一致
 *        
 * @author Alexia
 * @date  2013-10-15
 */
public class TransientTest {
    public static void main(String[] args) {
        User user = new User();
        user.setUsername("Alexia");
        user.setPasswd("123456");
        System.out.println("read before Serializable: ");
        System.out.println("username: " + user.getUsername());
        System.err.println("password: " + user.getPasswd());
        try {
            ObjectOutputStream os = new ObjectOutputStream(
                    new FileOutputStream("C:/user.txt"));
            os.writeObject(user); // 将User对象写进文件
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(
                    "C:/user.txt"));
            user = (User) is.readObject(); // 从流中读取User的数据
            is.close();
            System.out.println("\nread after Serializable: ");
            System.out.println("username: " + user.getUsername());
            System.err.println("password: " + user.getPasswd());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
class User implements Serializable {
    private static final long serialVersionUID = 8294180014912103005L;  
    private String username;
    private transient String passwd;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPasswd() {
        return passwd;
    }
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
}

The output is:

read before Serializable: 
username: Alexia
password: 123456
read after Serializable: 
username: Alexia
password: null

The password field is null, indicating that there is no need for deserialization at all No information was obtained from the file.

2. Summary of transient use

1) Once a variable is modified by transient, the variable will no longer be part of the object's persistence, and the content of the variable cannot be serialized after serialization. Get access.

2) The transient keyword can only modify variables, but not methods and classes. Note that local variables cannot be modified by the transient keyword. If the variable is a user-defined class variable, the class needs to implement the Serializable interface.

3) Variables modified by the transient keyword can no longer be serialized. A static variable cannot be serialized regardless of whether it is modified by transient.

The third point may be confusing to some people, because it is found that after adding the static keyword before the username field in the User class, the program running result remains unchanged, that is, the static username is also read as "Alexia" "Well, doesn't this contradict the third point? This is actually the case: The third point is indeed true (a static variable cannot be serialized regardless of whether it is modified by transient). After deserialization, the value of the static variable username in the class is the value of the corresponding static variable in the current JVM. , this value is derived from JVM and not deserialization. Don’t believe it? Okay, let me prove it below:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
 * @description 使用transient关键字不序列化某个变量
 *        注意读取的时候,读取数据的顺序一定要和存放数据的顺序保持一致
 *        
 * @author Alexia
 * @date  2013-10-15
 */
public class TransientTest {
    public static void main(String[] args) {
        User user = new User();
        user.setUsername("Alexia");
        user.setPasswd("123456");
        System.out.println("read before Serializable: ");
        System.out.println("username: " + user.getUsername());
        System.err.println("password: " + user.getPasswd());
        try {
            ObjectOutputStream os = new ObjectOutputStream(
                    new FileOutputStream("C:/user.txt"));
            os.writeObject(user); // 将User对象写进文件
            os.flush();
            os.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            // 在反序列化之前改变username的值
            User.username = "jmwang";
            ObjectInputStream is = new ObjectInputStream(new FileInputStream(
                    "C:/user.txt"));
            user = (User) is.readObject(); // 从流中读取User的数据
            is.close();
            System.out.println("\nread after Serializable: ");
            System.out.println("username: " + user.getUsername());
            System.err.println("password: " + user.getPasswd());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
class User implements Serializable {
    private static final long serialVersionUID = 8294180014912103005L;  
    public static String username;
    private transient String passwd;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPasswd() {
        return passwd;
    }
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
}

The running result is:

read before Serializable: 
username: Alexia
password: 123456
read after Serializable: 
username: jmwang
password: null

This shows that the static variable username in the class after deserialization The value is the value of the corresponding static variable in the current JVM, which is the modified jmwang, not the value Alexia during serialization.

3. Transient usage details - Can variables modified by the transient keyword really not be serialized?

Consider the following example:

import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
/**
 * @descripiton Externalizable接口的使用
 * 
 * @author Alexia
 * @date 2013-10-15
 *
 */
public class ExternalizableTest implements Externalizable {
    private transient String content = "是的,我将会被序列化,不管我是否被transient关键字修饰";
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(content);
    }
    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        content = (String) in.readObject();
    }
    public static void main(String[] args) throws Exception {
        ExternalizableTest et = new ExternalizableTest();
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                new File("test")));
        out.writeObject(et);
        ObjectInput in = new ObjectInputStream(new FileInputStream(new File(
                "test")));
        et = (ExternalizableTest) in.readObject();
        System.out.println(et.content);
        out.close();
        in.close();
    }
}

Will the content variable be serialized? Well, I output all the answers. Yes, the running result is:

是的,我将会被序列化,不管我是否被transient关键字修饰



Why is this? It’s not that the class variables are transient key Will word modification not be able to be serialized later?

We know that in Java, object serialization can be achieved by implementing two interfaces. If the Serializable interface is implemented, all serialization will be performed automatically. If the Externalizable interface is implemented, then Nothing can be serialized automatically. You need to manually specify the variables to be serialized in the writeExternal method. This has nothing to do with whether it is modified by transient. Therefore, the second example outputs the initialized content of the variable content, not null.

The above is the summary of Java transient keyword usage. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:Things about Java GC (2)Next article:Things about Java GC (2)