Scala 和 Java 内存模型
Java 内存模型(自 1.5 起)对待 final
字段与非 final
字段的方式不同。特别是,如果 this
引用在构造期间不会转义,则即使对象可用,也保证对构造函数中的 final
字段的写入在其他线程上可见通过数据竞争到另一个线程。 (写入非 final
字段不保证可见,因此如果您不正确地发布它们,另一个线程可能会看到它们处于部分构造的状态。)
是否有任何关于如何/如果Scala 编译器为类创建 final
(而不是非 final
)支持字段?我查看了语言规范并搜索了网络,但找不到任何明确的答案。 (相比之下,@scala.volatile
注释被记录为将字段标记为易失性
)
The Java Memory Model (since 1.5) treats final
fields differently to non-final
fields. In particular, provided the this
reference doesn't escape during construction, writes to final
fields in the constructor are guaranteed to be visible on other threads even if the object is made available to the other thread via a data race. (Writes to non-final
fields aren't guaranteed to be visible, so if you improperly publish them, another thread could see them in a partially constructed state.)
Is there any documentation on how/if the Scala compiler creates final
(rather than non-final
) backing fields for classes? I've looked through the language specification and searched the web but can't find any definitive answers. (In comparison the @scala.volatile
annotation is documented to mark a field as volatile
)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我深入研究历史,找出改变的时间。
语言规范未涵盖 Scala 到 JVM 的投影。
I dug through the history to find out when the change was made.
The projection of Scala into the JVM isn't covered by the language specification.
当您将某些内容声明为
val
时,它会创建一个final
字段。任何可以修改引用的内容,例如var
,(显然)不能是下面的final
。这意味着 case 类也包含 Final 字段(因为 case 类构造函数的参数隐式是 val )
It creates a
final
field when you declare something as aval
. Anything whose references can be modified, such as avar
, can (obviously) not befinal
underneath.This means that
case classes
contain final fields also (as the arguments to a case class constructor are implicitlyval
s)我已在 Scala bug 系统中提交了一个文档错误。
I've filed a documentation bug for this in the Scala bug system.