为什么 Java 有 瞬态 字段?
原文由 Animesh 发布,翻译遵循 CC BY-SA 4.0 许可协议
在了解 transient
关键字之前,必须了解序列化的概念。如果读者了解连载,请跳过第一点。
序列化是使对象的状态持久化的过程。这意味着对象的状态被转换为字节流,用于持久化(例如在文件中存储字节)或传输(例如通过网络发送字节)。同样,我们可以使用反序列化从字节中取回对象的状态。这是 Java 编程中的重要概念之一,因为序列化主要用于网络编程。需要通过网络传输的对象必须转换为字节。为此,每个类或接口都必须实现 Serializable
接口。它是一个没有任何方法的标记接口。
transient
关键字及其用途是什么?默认情况下,对象的所有变量都会转换为持久状态。在某些情况下,您可能希望避免保留某些变量,因为您不需要保留这些变量。因此,您可以将这些变量声明为 transient
。如果变量声明为 transient
,那么它将不会被持久化。这就是 transient
关键字的主要目的。
我想用下面的例子(借用 这篇文章)来解释以上两点:
package javabeat.samples; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class NameStore implements Serializable{ private String firstName; private transient String middleName; private String lastName; public NameStore (String fName, String mName, String lName){ this.firstName = fName; this.middleName = mName; this.lastName = lName; } public String toString(){ StringBuffer sb = new StringBuffer(40); sb.append("First Name : "); sb.append(this.firstName); sb.append("Middle Name : "); sb.append(this.middleName); sb.append("Last Name : "); sb.append(this.lastName); return sb.toString(); } } public class TransientExample{ public static void main(String args[]) throws Exception { NameStore nameStore = new NameStore("Steve", "Middle","Jobs"); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("nameStore")); // writing to object o.writeObject(nameStore); o.close(); // reading from object ObjectInputStream in = new ObjectInputStream(new FileInputStream("nameStore")); NameStore nameStore1 = (NameStore)in.readObject(); System.out.println(nameStore1); } }
输出如下:
First Name : Steve Middle Name : null Last Name : Jobs
Middle Name 声明为 transient
,因此它不会存储在持久存储中。
原文由 Rahul Saxena 发布,翻译遵循 CC BY-SA 4.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
Java 中的
transient
关键字用于指示字段不应该是序列化(这意味着保存,如文件)过程的一部分。来自 Java 语言规范,Java SE 7 版, 第 8.3.1.3 节。
transient
领域:例如,您可能有从其他字段派生的字段,并且只能以编程方式完成,而不是通过序列化来持久化状态。
这是一个
GalleryImage
类,其中包含图像和从图像派生的缩略图:在此示例中,
thumbnailImage
是通过调用generateThumbnail
方法生成的缩略图。thumbnailImage
字段标记为transient
,因此只有原始的image
被序列化,而不是保留原始图像和缩略图。这意味着保存序列化对象所需的存储空间更少。 (当然,这可能是可取的,也可能不是可取的,这取决于系统的要求——这只是一个例子。)在反序列化时,将调用
readObject
方法执行任何必要的操作,将对象的状态恢复到序列化发生时的状态。这里需要生成缩略图,所以重写readObject
方法,调用generateThumbnail
方法生成缩略图。有关其他信息,文章 发现 Java 序列化 API 的秘密(最初在 Sun Developer Network 上可用)有一节讨论了
transient
关键字的使用并展示了一个场景防止某些字段的序列化。