coo*_*ird 1623
transient
Java中的关键字用于指示字段不应该是序列化(这意味着保存,比如文件)过程的一部分.
来自Java语言规范,Java SE 7 Edition,第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();
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,thumbnailImage
是通过调用generateThumbnail
方法生成的缩略图图像.
该thumbnailImage
字段被标记为transient
,因此只有原始image
序列化而不是保留原始图像和缩略图图像.这意味着保存序列化对象所需的存储空间更少.(当然,根据系统的要求,这可能是也可能不合适 - 这只是一个例子.)
在反序列化时,readObject
调用该方法以执行将对象的状态恢复回序列化发生状态所需的任何操作.这里,需要生成缩略图,因此readObject
重写该方法,以便通过调用generateThumbnail
方法生成缩略图.
有关其他信息,请参阅" 发现Java序列化API的秘密"一文(最初在Sun Developer Network上提供),其中有一节讨论了使用transient
关键字并使用关键字来防止某些字段序列化的方案.
Rah*_*ena 417
在理解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);
}
}
Run Code Online (Sandbox Code Playgroud)
输出将如下:
First Name : Steve
Middle Name : null
Last Name : Jobs
Run Code Online (Sandbox Code Playgroud)
中间名声明为transient
,因此它不会存储在持久存储中.
Bri*_*new 82
允许您定义不想序列化的变量.
在对象中,您可能拥有不希望序列化/持久化的信息(可能是对父工厂对象的引用),或者序列化可能没有意义.将这些标记为"瞬态"意味着序列化机制将忽略这些字段.
Shr*_*ari 35
我的小贡献:
什么是瞬态场?
基本上,使用transient
关键字修改的任何字段都是瞬态字段.
为什么Java中需要瞬态字段?
该transient
关键字使您可以控制序列化过程,并允许您从此过程中排除某些对象属性.序列化过程用于持久化Java对象,主要是为了在传输或非活动状态时保留它们的状态.有时,不序列化对象的某些属性是有意义的.
您应该在哪些字段标记瞬态?
现在我们知道transient
关键字和瞬态字段的用途,了解哪些字段标记瞬态非常重要.静态字段也没有序列化,因此相应的关键字也可以实现.但这可能会破坏你的课堂设计; 这是transient
关键字拯救的地方.我尽量不允许其值可以从其他字段派生的字段被序列化,所以我将它们标记为瞬态.如果您有一个字段,interest
其值可以从其他字段(principal
,rate
&time
)计算,则无需序列化它.
另一个很好的例子是文章字数.如果要保存整篇文章,则实际上不需要保存单词计数,因为可以在文章被"反序列化"时计算.或者想想伐木工; Logger
实例几乎从不需要序列化,因此它们可以是瞬态的.
Adr*_*ore 25
甲transient
变量是可以不被序列化的变量.
想到这可能有用的一个例子是,变量只在特定对象实例的上下文中有意义,并且在序列化和反序列化对象后变为无效.在这种情况下,改变这些变量是有用的,null
这样您就可以在需要时使用有用的数据重新初始化它们.
And*_*anu 15
transient
用于表示不需要序列化类字段.可能最好的例子是一个Thread
领域.通常没有理由对序列化进行序列化Thread
,因为它的状态非常"特定于流程".
Dra*_*Fax 14
除本机java之外的序列化系统也可以使用此修饰符.例如,Hibernate不会持久标记用@Transient或transient修饰符标记的字段.兵马俑也尊重这个修饰符.
我相信修饰符的比喻意思是"此字段仅供内存使用.不要以任何方式持久存在或将其移出此特定VM.它不可移植".即你不能在另一个VM内存空间中依赖它的值.很像volatile,意味着你不能依赖某些内存和线程语义.
在回答这个问题之前,我必须向您解释SERIALIZATION,因为如果您了解科学计算机中序列化的含义,您就可以轻松理解这个关键字.
序列化
当通过网络传输对象/保存在物理介质(文件,...)上时,对象必须"序列化".序列化转换字节状态对象系列.这些字节在网络上发送/保存,并从这些字节重新创建对象.
例
public class Foo implements Serializable
{
private String attr1;
private String attr2;
...
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你想不TRANSFERT/救了这个对象的字段SO,您可以使用关键字 transient
private transient attr2;
Run Code Online (Sandbox Code Playgroud)
当您不想共享一些与序列化相关的敏感数据时,需要它。
根据谷歌瞬态含义==仅持续很短的时间;暂时的。
现在,如果你想在java中使任何东西瞬态,请使用transient关键字。
问:在哪里使用瞬态?
答:一般在java中我们可以通过获取变量并将这些变量写入文件来将数据保存到文件中,这个过程称为序列化。现在,如果我们想避免将变量数据写入文件,我们可以将该变量设置为瞬态变量。
transient int result=10;
Run Code Online (Sandbox Code Playgroud)
注意:瞬态变量不能是局部的。