什么是瞬态和挥发性修饰剂?


126

有人可以解释Java中transientvolatile修饰符的含义吗?


3
显然这不是一个问题,而且无论如何都是重复的(这就是为什么我投票决定关闭)。参见例如Java为什么具有瞬态变量?什么时候才在Java中使用volatile关键字?(以及许多其他)。
Pascal Thivent

可能重复使用的是什么“ volatile”?
杰夫

18
这是一个完全有效的问题,等同于:stackoverflow.com/questions/215497/...
巴里Fruitman

Answers:


156

volatiletransient改性剂可以被施加到的类的字段1,不论字段类型。除此之外,它们是无关的。

transient修饰符告诉Java对象序列化子系统序列化类的实例时排除领域。然后反序列化对象时,该字段将被初始化为默认值;即null对于引用类型,零或false对于原始类型。请注意,JLS(请参阅8.3.1.3)没有说明transient含义,而是遵循Java Object Serialization Specification。其他序列化机制可能会注意字段的性质transient。否则他们可能会忽略它。

(请注意,JLS允许将static字段声明为transient。此组合对于Java对象序列化没有意义,因为它无论如何都不会序列化静态变量。但是,在其他情况下它也可能有意义,因此对于不完全禁止它。)

volatile修饰符告诉JVM是写入到现场应始终同步刷新到内存中,并读取该领域应始终从内存中读取。这意味着可以在多线程应用程序中安全地访问和更新标记为易失性的字段,而无需使用基于本机或基于标准库的同步。同样,对易失性字段的读取和写入也是原子的。(这并不适用于>>非易失性<< longdouble领域,这可能会受到在某些JVM上“字撕裂”。)的JLS的有关部分是8.3.1.417.417.7


1-但不适用于局部变量或参数。


10

volatiletransient关键字

1)transient关键字与实例变量一起使用,以将其从序列化过程中排除。如果是字段,则transient其值将不会保留。

另一方面,volatile关键字用于将Java变量标记为“正在存储在主存储器中”。

每次读取volatile变量都会从计算机的主内存中读取,而不是从CPU缓存中读取,并且对volatile变量的每次写入都将写入主内存中,而不仅是CPU缓存中。

2)transient关键字不能与static关键字一起使用,但volatile可以与一起使用static

3)transient在反序列化期间,变量使用默认值初始化,并且必须由应用程序代码来处理值的赋值或恢复。

有关更多信息,请参阅我的博客:http :
//javaexplorer03.blogspot.in/2015/07/difference-between-volatile-and.html


2
的原因transient变量不能与一起使用的static关键字是属于一类,而不是任何单独的实例静态变量。序列化的概念与对象的当前状态有关。只有与类的特定实例相关联的数据
才被

实际上,JLS允许statictransient一起使用。问题在于它没有多大意义,因为典型的序列化机制无论如何都不会持久保存静态数据。
斯蒂芬·C

7

易失性意味着其他线程可以编辑该特定变量。因此,编译器允许访问它们。

http://www.javamex.com/tutorials/synchronization_volatile.shtml

瞬态意味着序列化对象时,它将在反序列化时返回其默认值

http://www.geekinterview.com/question_details/2


5
“因此,编译器允许访问它们。” 您的句子表明,默认情况下,线程无权访问。现在,我阅读了链接和我理解的其他答案:编译器不对变量进行任何特定于线程的中间存储,因此其他线程可以立即看到更改。
helios 2010年

我对volatile的C使用和volatile的Java使用感到困惑。我的意思是编译器确保它可以访问字段的actaul值,而不是缓存的值。
雷诺斯

这意味着更多。
斯蒂芬·C

1

短暂的 :

首先需要知道它在哪里需要如何弥合差距。

1)Access修饰符瞬态仅适用于可变组件。它不会与方法或类一起使用。

2)瞬态关键字不能与静态关键字一起使用。

3)什么是序列化以及在何处使用?序列化是使对象的状态持久化的过程。这意味着对象的状态将转换为字节流,用于持久化(例如,将字节存储在文件中)或传输(例如,通过网络发送字节)。同样,我们可以使用反序列化从字节中恢复对象的状态。这是Java编程中的重要概念之一,因为序列化主要用于网络编程中。需要通过网络传输的对象必须转换为字节。在理解瞬时关键字之前,必须先了解序列化的概念。如果读者了解序列化,请跳过第一点。

注1)瞬态主要用于序列化过程。为此,该类必须实现java.io.Serializable接口。该类中的所有字段都必须可序列化。如果字段不可序列化,则必须将其标记为瞬态。

注2)进行反序列化处理时,根据类型约束将其设置为默认值-零,false或null。

注3)瞬态关键字及其用途?用瞬时修饰符声明的字段将不参与序列化过程。当对象被序列化(以任何状态保存)时,其瞬态字段的值在串行表示中将被忽略,而瞬态字段以外的其他字段将参与序列化过程。这是瞬时关键字的主要目的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.