为什么 Java 有瞬态字段?

新手上路,请多包涵

为什么 Java 有 瞬态 字段?

原文由 Animesh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 487
2 个回答

Java 中的 transient 关键字用于指示字段不应该是序列化(这意味着保存,如文件)过程的一部分。

来自 Java 语言规范,Java SE 7 版第 8.3.1.3 节。 transient 领域

变量可能被标记为 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 Developer Network 上可用)有一节讨论了 transient 关键字的使用并展示了一个场景防止某些字段的序列化。

原文由 coobird 发布,翻译遵循 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 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题