search
HomeJavaJavaBaseDetailed explanation of transient keyword in java

To be honest, friends who have studied Java for a while are still very unfamiliar with the keyword transient and have rarely used it, but the keyword transient plays an indispensable role in Java! If I want to talk about it, I think the most likely place to appear is when it comes to object streams (also called serialized streams) in IO streams!

Detailed explanation of transient keyword in java

I believe that many people will not care about this keyword until they encounter it. I remember that the first time bloggers encountered the transient keyword was when reading the JDK source code. In the process of learning Java, the reason why the transient keyword is rare is actually inseparable from its function: the main function of the transient keyword is to prevent certain member attribute variables modified by the transient keyword from being serialized. In fact, it is precisely for this reason that serialization operations are rarely used in the learning process, usually in actual development! As for serialization, I believe that many novices have been confused or have no specific concept. This is not a problem. The following blogger will clearly let you remember what serialization is, ensuring that you will never forget it in this life (it seems a bit Exaggerated, a bit pretentious, I feel like I’m going to be beaten)

1. What is serialization?

Speaking of serialization, another concept that comes with it is deserialization. Don’t panic, little white children’s shoes. Remembering serialization is equivalent to remembering deserialization, because deserialization Serialization is the reverse of serialization, so the blogger recommends just remembering the concept of serialization to avoid confusing yourself.

(Recommended video: java video tutorial)

Serialization of professional terminology definitions :

Java provides a mechanism for object serialization. An object can be represented by a byte sequence that contains information such as the object's data, the object's type, and the attributes stored in the object. After the byte sequence is written to the file, it is equivalent to persisting the information of an object in the file. Conversely, the byte sequence can be read back from the file, the object reconstructed, and deserialized. The object's data, the object's type, and the data information stored in the object can all be used to create objects in memory.

Serialization: Byte——> Object

In fact, what I summarized is the above conclusion. If you don’t understand, refer directly to the definition of professional terms, and remember it after you understand it. Just remember my words. If you can’t remember, please beat me to death.

Diagram to understand serialization:

Detailed explanation of transient keyword in java

2. Why serialization?

The concept of serialization was mentioned in the previous section. After knowing the concept, we must know why we need to serialize.

Before I talk about the reasons why serialization is necessary, let me give you a chestnut as a blogger:

Just like when you go to the street to buy groceries, the general operation is to package them in plastic bags until you go home. When it's time to cook, take out the dishes. And this series of operations is like serialization and deserialization!

Serialization of objects in Java refers to converting objects into byte sequences. These byte sequences contain the data and information of the object. A serialized object can be written to In databases or files, it can also be used for network transmission. Generally, when we use cache (not enough memory space may be stored locally on the hard disk) or remotely call rpc (network transmission), we often need to make our entity classes implement the Serializable interface. , the purpose is to make it serializable.

Chestnuts modified with the transient keyword during the development process:

If a user has some passwords and other information, for the sake of security, they do not want to be transmitted during network operations, these information correspond to You can add the transient keyword to the variable. 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.

Examples that do not require the transient keyword modification during the development process:

1. Field values ​​in the class can be derived based on other fields.

2. Depending on the specific business requirements, which fields do not want to be serialized;

I wonder if you have ever thought about why they should not be serialized? In fact, it is mainly to save storage space. Optimize the program!

PS: I remember when I was looking at the HashMap source code, I found that a field was modified with transient. I think it makes sense. There is really no need to serialize the modCount field because it is meaningless. ModCount is mainly Used to determine whether the HashMap has been modified (modCount will be incremented during put and remove operations). For this kind of variable, it can be any value at the beginning, of course 0 (new, deserialized, or cloned). It is always 0 when it comes out), there is no need to persist its value.

Of course, the ultimate purpose after serialization is to deserialize and restore it to the original Java object. Otherwise, what would you do after serialization? Just like buying groceries, wrapping them in plastic bags is for the convenience of getting home safely. Remove the plastic bag, so the serialized byte sequence can be restored to a Java object. This process is deserialization.

3. The use of serialization and transient

1. The class of the object that needs to be serialized must implement the serialization interface: Java.lang.Serializable interface ( A flag interface without any abstract methods), most classes in Java implement this interface, such as: String, Integer class, etc. Classes that do not implement this interface will not serialize or deserialize any state and will throw NotSerializableException exception.

2. The bottom layer will judge that if the current object is an instance of Serializable, serialization is allowed. The Java object instanceof Serializable is used to judge.

3. Use the object stream ObjectOutputStream in Java to complete serialization and ObjectInputStream stream deserialization

==ObjectOutputStream: serialization operation through the writeObject() method== 

==ObjectInputStream: Deserialization operation through readObject() method==

4. All properties of this class must be serializable. If there is an attribute that does not need to be serializable, the attribute must be marked as transient and modified using the transient keyword.

Detailed explanation of transient keyword in java

Because of the bytes, it must involve stream operations, that is, the object stream is also called the serialized stream ObjectOutputstream. Let’s analyze the serialization in various situations. Action code!

Here, I really strongly recommend readers who read the Yichun blog, please try to knock it, remember to take it with you at a glance or copy it and run it, especially Xiaobai children's shoes, believe me! You will definitely gain something different. !

3.1. Serialization without implementing Serializable interface

package TransientTest;
import java.io.*;

class UserInfo { //================================注意这里没有实现Serializable接口
    private String name;
    private transient String password;

    public UserInfo(String name, String psw) {
        this.name = name;
        this.password = psw;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
            "name='" + name + '\'' +
            ", password='" + password + '\'' +
            '}';
    }
}

public class TransientDemo {
    public static void main(String[] args) {

        UserInfo userInfo = new UserInfo("老王", "123");
        System.out.println("序列化之前信息:" + userInfo);

        try {
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("userinfo.txt"));
            output.writeObject(new UserInfo("老王", "123"));
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Running results

Detailed explanation of transient keyword in java

3.2. Serialization with Serializable interface implemented

When we add the Serializable interface and run it again, we will find that the content of the userinfo.txt file that appears in the project is like this:

Detailed explanation of transient keyword in java

In fact, this is not the point. The point is that the serialization operation was successful!

3.3. Ordinary serialization situation

package TransientTest;
import java.io.*;

class UserInfo implements Serializable { //第一步实现Serializable接口
    private String name;
    private String password; //都是普通属性==============================

    public UserInfo(String name, String psw) {
        this.name = name;
        this.password = psw;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
            "name='" + name + '\'' +
            ", password='" + password + '\'' +
            '}';
    }
}

public class TransientDemo {
    public static void main(String[] args) throws ClassNotFoundException {

        UserInfo userInfo = new UserInfo("程序员老王", "123");
        System.out.println("序列化之前信息:" + userInfo);

        try {
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("userinfo.txt")); //第二步开始序列化操作
            output.writeObject(new UserInfo("程序员老王", "123"));
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream input = new ObjectInputStream(new FileInputStream("userinfo.txt")); //第三步开始反序列化操作
            Object o = input.readObject(); //ObjectInputStream的readObject方法会抛出ClassNotFoundException
            System.out.println("序列化之后信息:" + o);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Running result:

序列化之前信息:UserInfo{name='程序员老王', password='123'}
序列化之后信息:UserInfo{name='程序员老王', password='123'}

3.4. Transient serialization situation

package TransientTest;
import java.io.*;

class UserInfo implements Serializable { //第一步实现Serializable接口
    private String name;
    private transient String password; //特别注意:属性由transient关键字修饰===========

    public UserInfo(String name, String psw) {
        this.name = name;
        this.password = psw;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
            "name='" + name + '\'' +
            ", password='" + password + '\'' +
            '}';
    }
}

public class TransientDemo {
    public static void main(String[] args) throws ClassNotFoundException {

        UserInfo userInfo = new UserInfo("程序员老王", "123");
        System.out.println("序列化之前信息:" + userInfo);

        try {
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("userinfo.txt")); //第二步开始序列化操作
            output.writeObject(new UserInfo("程序员老王", "123"));
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream input = new ObjectInputStream(new FileInputStream("userinfo.txt")); //第三步开始反序列化操作
            Object o = input.readObject(); //ObjectInputStream的readObject方法会抛出ClassNotFoundException
            System.out.println("序列化之后信息:" + o);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Running result:

序列化之前信息:UserInfo{name='程序员老王', password='123'}
序列化之后信息:UserInfo{name='程序员老王', password='null'}

Pay special attention to the results. The attribute value added with transient modification is the default value null! If the attribute modified by transient is of type int, then its value must be 0 after being serialized. Of course, you can try it. What does this mean? It means that attributes marked as transient will not be saved when the object is serialized (or the variable will not be persisted)

3.5. Static serialization situation

package TransientTest;
import java.io.*;

class UserInfo implements Serializable { //第一步实现Serializable接口
    private String name;
    private static String password; //特别注意:属性由static关键字修饰==============

    public UserInfo(String name, String psw) {
        this.name = name;
        this.password = psw;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
            "name='" + name + '\'' +
            ", password='" + password + '\'' +
            '}';
    }
}

public class TransientDemo {
    public static void main(String[] args) throws ClassNotFoundException {

        UserInfo userInfo = new UserInfo("程序员老王", "123");
        System.out.println("序列化之前信息:" + userInfo);

        try {
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("userinfo.txt")); //第二步开始序列化操作
            output.writeObject(new UserInfo("程序员老王", "123"));
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            ObjectInputStream input = new ObjectInputStream(new FileInputStream("userinfo.txt")); //第三步开始反序列化操作
            Object o = input.readObject(); //ObjectInputStream的readObject方法会抛出ClassNotFoundException
            System.out.println("序列化之后信息:" + o);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Running results:

序列化之前信息:UserInfo{name='程序员老王', password='123'}
序列化之后信息:UserInfo{name='程序员老王', password='123'}

At this time, you will mistakenly think that the static modification has also been serialized. In fact, it is not the case. In fact, it is easy to get confused here! Obviously taking out null (default value) can show that it will not be serialized. It is obvious that it has not become the default value. Why do you still say that static will not be serialized?

In fact, the value of the static variable name in the class after deserialization is actually the value of the corresponding static variable in the current JVM. This value is in the JVM and is not derived from deserialization. In other words, variables modified by static do not participate in serialization! But we can’t say it without proof, yes, then let’s compare the two programs and we will understand!

The first program: This is a name attribute program that has not been modified by static:

package Thread;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class UserInfo implements Serializable {
    private String name;
    private transient String psw;

    public UserInfo(String name, String psw) {
        this.name = name;
        this.psw = psw;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPsw() {
        return psw;
    }

    public void setPsw(String psw) {
        this.psw = psw;
    }

    public String toString() {
        return "name=" + name + ", psw=" + psw;
    }
}
public class TestTransient {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo("程序员老过", "456");
        System.out.println(userInfo);
        try {
            // 序列化,被设置为transient的属性没有被序列化
            ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("UserInfo.txt"));
            o.writeObject(userInfo);
            o.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        try {
            //在反序列化之前改变name的值 =================================注意这里的代码
            userInfo.setName("程序员老改");
            // 重新读取内容
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("UserInfo.txt"));
            UserInfo readUserInfo = (UserInfo) in .readObject();
            //读取后psw的内容为null
            System.out.println(readUserInfo.toString());
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
}

Running results:

name=程序员老过, psw=456name=程序员老过, psw=null

Running results from the program As can be seen from the figure, trying to change the value of name before deserialization was unsuccessful!

The second program: This is a statically modified name attribute program:

package Thread;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class UserInfo implements Serializable {
    private static final long serialVersionUID = 996890129747019948 L;
    private static String name;
    private transient String psw;

    public UserInfo(String name, String psw) {
        this.name = name;
        this.psw = psw;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPsw() {
        return psw;
    }

    public void setPsw(String psw) {
        this.psw = psw;
    }

    public String toString() {
        return "name=" + name + ", psw=" + psw;
    }
}
public class TestTransient {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo("程序员老过", "456");
        System.out.println(userInfo);
        try {
            // 序列化,被设置为transient的属性没有被序列化
            ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("UserInfo.txt"));
            o.writeObject(userInfo);
            o.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        try {
            //在反序列化之前改变name的值
            userInfo.setName("程序员老改");
            // 重新读取内容
            ObjectInputStream in = new ObjectInputStream(new FileInputStream("UserInfo.txt"));
            UserInfo readUserInfo = (UserInfo) in .readObject();
            //读取后psw的内容为null
            System.out.println(readUserInfo.toString());
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
}

Running results:

name=程序员老过, psw=456name=程序员老改, psw=null

From the program running results It can be seen that trying to change the value of name before deserialization is done by programmers, and the result is successful! Is it very clear now if we compare the two programs?

The member attributes modified by the static keyword are loaded into memory better than non-static member attributes. At the same time, static is also better than objects entering memory. Member variables modified by static cannot be serialized, and all objects are serialized. A static variable is not part of the object's state, so it does not participate in serialization. So it is useless to declare static variables as transient variables. Therefore, the value of the static variable name in the class after deserialization is actually the value of the corresponding static variable in the current JVM. This value is in the JVM and is not derived from deserialization.

3.6. Final serialization situation

For the final keyword, the final variable will directly participate in serialization through the value. As for the code program, I will not post it anymore. You can try it. Check the final modification!

The main thing to note is that final and transient can modify the same variable at the same time, and the result is the same. It has no impact on transient. I mainly mention it here. I hope you will not be confused when you encounter these situations in development in the future. water!

4. The role of serialVersionUID in java classes

Since the transient keyword has been mentioned, serialization has to be mentioned. Since serialization has been mentioned, serialVersionUID has to be mentioned. What is it? Woolen cloth? Basically, this serialVersionUID will exist if there is serialization.

Detailed explanation of transient keyword in java

#serialVersionUID applies to Java's serialization mechanism. Simply put, Java's serialization mechanism verifies version consistency by judging the serialVersionUID of the class. When deserializing, the JVM will compare the serialVersionUID in the passed byte stream with the serialVersionUID of the corresponding local entity class. If they are the same, they are considered consistent and can be deserialized. Otherwise, a serialized version will appear. Inconsistent exceptions, namely InvalidCastException, can sometimes be written or not during development. It is recommended that it be written.

5. Summary of transient keyword

1. If the variable is modified by transient, the variable will not be serialized
2. The transient keyword only Variables can be modified, but methods and classes cannot be modified.
3. Variables modified by the static keyword do not participate in serialization. A static variable cannot be serialized regardless of whether it is modified by transient.
4. The final variable value participates in serialization, and final transient modifies the variable at the same time. Final will not affect transient and will not participate in serialization either.

The second point to note is: local variables are Cannot be modified by the transient keyword. If the variable is a user-defined class variable, the class needs to implement the Serializable interface

The third point to note is: the value of the static variable in the class after deserialization is actually the corresponding static variable in the current JVM The value is in the JVM and is not derived from deserialization.

Conclusion: Modified by the transient keyword, it will not be serialized. The advantage is that it can save storage space. Optimize the program! What follows is that the fields modified by transient will be recalculated and initialized!

This article comes from php Chinese website, java tutorial column, welcome to learn!

The above is the detailed content of Detailed explanation of transient keyword in java. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:博客园. If there is any infringement, please contact admin@php.cn delete
带你搞懂Java结构化数据处理开源库SPL带你搞懂Java结构化数据处理开源库SPLMay 24, 2022 pm 01:34 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

Java集合框架之PriorityQueue优先级队列Java集合框架之PriorityQueue优先级队列Jun 09, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

完全掌握Java锁(图文解析)完全掌握Java锁(图文解析)Jun 14, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

一起聊聊Java多线程之线程安全问题一起聊聊Java多线程之线程安全问题Apr 21, 2022 pm 06:17 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

详细解析Java的this和super关键字详细解析Java的this和super关键字Apr 30, 2022 am 09:00 AM

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

Java基础归纳之枚举Java基础归纳之枚举May 26, 2022 am 11:50 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

java中封装是什么java中封装是什么May 16, 2019 pm 06:08 PM

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。

归纳整理JAVA装饰器模式(实例详解)归纳整理JAVA装饰器模式(实例详解)May 05, 2022 pm 06:48 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于设计模式的相关问题,主要将装饰器模式的相关内容,指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式,希望对大家有帮助。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)