The transient Keyword in Java – Java中的瞬时关键字

最后修改: 2020年 11月 5日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.绪论

In this article, we’ll first understand the transient keyword, and then we’ll see its behavior through examples.

在这篇文章中,我们将首先理解transient关键字,然后我们将通过实例看到其行为。

2. Usage of transient

2.transient的用途

Let’s first understand the serialization before moving to transient as it is used in the context of serialization.

让我们首先了解一下序列化,然后再来看看transient,因为它是在序列化的背景下使用的。

Serialization is the process of converting an object into a byte stream, and deserialization is the opposite of it.

序列化是将一个对象转换为字节流的过程,而反序列化则与之相反

When we mark any variable as transient, then that variable is not serialized. Since transient fields aren’t present in the serialized form of an object, the deserialization process would use the default values for such fields when creating an object out of the serialized form.

当我们将任何变量标记为transient时,该变量就不会被序列化。由于transient字段并不存在于对象的序列化形式中,当从序列化形式中创建一个对象时,反序列化过程将使用这些字段的默认值。

The transient keyword is useful in a few scenarios:

transient关键字在一些情况下很有用。

  • We can use it for derived fields
  • It is useful for fields that do not represent the state of the object
  • We use it for any non-serializable references

3. Example

3.例子

To see it in action, let’s first create a Book class whose object we would like to serialize:

为了看到它的作用,让我们首先创建一个Book类,我们想对其对象进行序列化。

public class Book implements Serializable {
    private static final long serialVersionUID = -2936687026040726549L;
    private String bookName;
    private transient String description;
    private transient int copies;
    
    // getters and setters
}

Here, we have marked description and copies as transient fields.

这里,我们把descriptioncopies标记为transient字段。

After creating the class, we’ll create an object of this class:

创建完这个类后,我们将创建这个类的一个对象。

Book book = new Book();
book.setBookName("Java Reference");
book.setDescription("will not be saved");
book.setCopies(25);

Now, we’ll serialize the object into a file:

现在,我们将把这个对象序列化到一个文件中。

public static void serialize(Book book) throws Exception {
    FileOutputStream file = new FileOutputStream(fileName);
    ObjectOutputStream out = new ObjectOutputStream(file);
    out.writeObject(book);
    out.close();
    file.close();
}

Let’s deserialize the object now from the file:

现在让我们从文件中反序列化这个对象。

public static Book deserialize() throws Exception {
    FileInputStream file = new FileInputStream(fileName);
    ObjectInputStream in = new ObjectInputStream(file);
    Book book = (Book) in.readObject();
    in.close();
    file.close();
    return book;
}

Finally, we’ll verify the values of the book object:

最后,我们将验证book对象的值。

assertEquals("Java Reference", book.getBookName());
assertNull(book.getDescription());
assertEquals(0, book.getCopies());

Here we see that bookName has been properly persisted. On the other hand, the copies field has value 0 and the description is null – the default values for their respective data types – instead of the original values.

这里我们看到bookName已经被正确地持久化了。另一方面,copies字段的值是0descriptionnull –它们各自数据类型的默认值 – 而不是原始值。

4. Behavior With final

4.与final的行为

Now, let’s see a case where we’ll use transient with the final keyword. For that, first, we’ll add a final transient element in our Book class and then create an empty Book object:

现在,让我们看看我们将使用transientfinal关键字的情况。为此,首先,我们将在我们的Book类中添加一个final transient元素,然后创建一个空的Book对象。

public class Book implements Serializable {
    // existing fields    
    
    private final transient String bookCategory = "Fiction";

    // getters and setters
}
Book book = new Book();

The final modifier makes no difference – because the field is transient, no value is saved for that field. During deserialization, the new Book object gets the default value Fiction that’s defined in the Book class, but that value doesn’t come from the serialization data:

最终修改器没有任何区别–因为该字段是transient,没有为该字段保存任何值。在反序列化过程中,新的Book对象会得到Book类中定义的默认值Fiction,但是这个值并不是来自序列化数据。

assertEquals("Fiction", book.getBookCategory());

5. Conclusion

5.总结

In this article, we saw the usage of the transient keyword and its behavior in serialization and deserialization.

在这篇文章中,我们看到了transient关键字的用法以及它在序列化和反序列化中的行为。

As always, all the code is available over on GitHub.

像往常一样,所有的代码都可以在GitHub上找到