为什么 Java 有瞬态字段?
为什么 Java 有瞬态字段?
Java 中的关键字用于指示字段不应是序列化(这意味着已保存,如文件)过程的一部分。transient
摘自 Java 语言规范,Java SE 7 版,第 8.3.1.3 节。短暂的
领域:
可以标记变量以指示它们不是对象的持久状态的一部分。
transient
例如,您可能具有从其他字段派生的字段,并且只应以编程方式执行此操作,而不是通过序列化来持久保存状态。
下面是一个类,其中包含图像和从图像派生的缩略图:GalleryImage
class GalleryImage implements Serializable
{
private Image image;
private transient Image thumbnailImage;
private void generateThumbnail()
{
// Generate thumbnail.
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
generateThumbnail();
}
}
在此示例中,是通过调用该方法生成的缩略图图像。thumbnailImage
generateThumbnail
该字段被标记为 ,因此只序列化原始图像,而不是同时保留原始图像和缩略图图像。这意味着保存序列化对象所需的存储更少。(当然,根据系统的要求,这可能是也可能不可取的 - 这只是一个例子。thumbnailImage
transient
image
在反序列化时,将调用 readObject
方法来执行将对象的状态还原回序列化发生的状态所需的任何操作。这里,需要生成缩略图,因此重写该方法,以便通过调用该方法生成缩略图。readObject
generateThumbnail
有关其他信息,文章发现 Java 序列化 API(最初在 Sun 开发人员网络上提供)的秘密有一节讨论关键字的使用,并介绍了使用关键字来防止某些字段序列化的方案。transient
在理解关键字之前,必须了解序列化的概念。如果读者知道序列化,请跳过第一点。transient
序列化是使对象的状态持久化的过程。这意味着对象的状态被转换为字节流,用于持久化(例如,在文件中存储字节)或传输(例如,通过网络发送字节)。同样,我们可以使用反序列化从字节中恢复对象的状态。这是Java编程中的重要概念之一,因为序列化主要用于网络编程。需要通过网络传输的对象必须转换为字节。为此,每个类或接口都必须实现可序列化
接口。它是一个没有任何方法的标记界面。
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
中间名声明为 ,因此它不会存储在持久性存储中。transient