为什么在Java中要使用“transient”关键字?

16

我遇到了一个与 Java 中 transient 关键字在 private 修饰符前使用有关的问题。

变量声明:

transient private ResourceBundle pageResourceBundle; 

我的课堂看起来像这样:

public class LoginViewModel extends AbstractViewModel {

    transient private ResourceBundle pageResourceBundle;

    @AfterCompose
    public void afterCompose(@ContextParam(ContextType.VIEW) Component view) {
        initializeLoginValues();
        boolean timeout = BooleanUtils.toBoolean(getHttpServletRequest().getParameter("timeout"));
        if (timeout) {
            Messagebox.show(pageResourceBundle.getText("MSG_SESSION_HAS_EXPIRED_PLEASE_LOGIN"), pageResourceBundle.getText("LABEL_ALERT"),
                    Messagebox.OK, Messagebox.ERROR);
        }
        view.getPage().setTitle(CsdcLicence.get().getApplicationName());
    }

我有一些问题。

1.为什么要在私有变量前使用transient关键字?

2.使用这个关键字的目的是什么?


8
你提供的链接已经回答了你的两个问题。你还有什么疑问?哪些内容还没有被涵盖到? - Peter Lawrey
@PeterLawrey 请修改我的问题,看看我的类是否实现了序列化。 - Sitansu
你的类可能会被你使用的库序列化,或者该库可能会将 transient 与模型一起用于其他目的。它可能会在视图中显示除了 transient 字段之外的所有字段。你需要阅读你所使用的库的文档。 - Peter Lawrey
有人能解释一下为什么我们想要故意在网络上丢失对象吗?有什么例子吗? - Mugen
4个回答

33

在Java中,瞬态变量不会被序列化。

当对象以字节流的形式持久化时,使用transient关键字标记成员变量不会被序列化。当对象通过网络传输时,需要将对象“序列化”。序列化将对象状态转换为序列化字节,这些字节将被发送到网络上,并从这些字节重新创建对象。使用Java transient 关键字标记的成员变量不会被传输,因此它们会有意地被丢失。

请查看 serialization 以了解更多信息,并参考此链接

示例

public class Foo implements Serializable
{
  private String saveMe;
  private transient String dontSaveMe;
  private transient String password;
  //...
}

在上面的例子中,dontSaveMepassword被声明为transient variables,因此它们不会被序列化。

5
“Never”太绝对了。它们默认情况下不会被序列化,但如果你编写自己的readObject()/writeObject()方法,就可以手动进行序列化。 - user207421

22

以下是需要翻译的内容:

假设通过公开可用的 Web 服务公开 User-Object。 您肯定想公开昵称、在线状态、电子邮件或位置等信息。 您绝对不想公开用户用于登录的密码。 尽管此密码可以是 User-Object 的属性,但在将对象序列化为用于上述 Web 服务的 JSON 字符串时,它不应被序列化。

一个简短的用例:
假设通过公开可用的 Web 服务公开 User-Object。 您肯定想公开昵称、在线状态、电子邮件或位置等信息。 您绝对不想公开用户用于登录的密码。 尽管此密码可以是 User-Object 的属性,但在将对象序列化为用于上述 Web 服务的 JSON 字符串时,它不应被序列化。


1
非常好的使用案例。我就是为了找这个而来的。 - abhy

7
transient关键字表示该对象不应该被序列化,也不应该被持久化。如果您不想序列化较重的对象(例如可以包含许多业务逻辑的Wrapper),可以使用它。 @Transient注释表示对象不应该被持久化(例如在使用Hibernate时),但它可以被序列化。
我包含了注释的解释,因为我记得两者之间曾经让我困惑过。 :-)

1
“transient” 只与序列化有关,其含义由 JLS 精确定义。 “@Transient” 是第三方定义的注释,如果不提供完全限定类名,则含义模糊不清。 - Marko Topolnik

3

transient用于指定对象的哪些属性不会被保存或序列化。例如,当将对象保存到文件中时,transient指定了哪些属性或属性在保存到文件时不会被保存。

当从文件重新创建对象时,该transient属性(或私有属性)的值不会重新创建,因为它从未保存或序列化到该文件中。 在某些情况下,您可能希望避免持久化对象的某些私有实例变量或属性,transient可以让您实现这一点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接