为什么`private val` 和`private final val` 不同? [英] Why are `private val` and `private final val` different?

查看:35
本文介绍了为什么`private val` 和`private final val` 不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以前认为 private valprivate final val 是一样的,直到我在 Scala Reference 中看到第 4.1 节:

I used to think that private val and private final val are same, until I saw section 4.1 in Scala Reference:

常量值定义的形式为

final val x = e

其中 e 是一个常量表达式(第 6.24 节).final 修饰符必须存在,并且不能给出类型注释.对常量值 x 的引用本身被视为常量表达式;在生成的代码中,它们被定义的右侧 e 替换.

where e is a constant expression (§6.24). The final modifier must be present and no type annotation may be given. References to the constant value x are themselves treated as constant expressions; in the generated code they are replaced by the definition’s right-hand side e.

我已经写了一个测试:

class PrivateVal {
  private val privateVal = 0
  def testPrivateVal = privateVal
  private final val privateFinalVal = 1
  def testPrivateFinalVal = privateFinalVal
}

javap -c 输出:

Compiled from "PrivateVal.scala"
public class PrivateVal {
  public int testPrivateVal();
    Code:
       0: aload_0       
       1: invokespecial #19                 // Method privateVal:()I
       4: ireturn       

  public int testPrivateFinalVal();
    Code:
       0: iconst_1      
       1: ireturn       

  public PrivateVal();
    Code:
       0: aload_0       
       1: invokespecial #24                 // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: iconst_0      
       6: putfield      #14                 // Field privateVal:I
       9: return
}

字节码正如Scala Reference所说:private val不是private final val.

The byte code is just as Scala Reference said: private val is not private final val.

为什么scalac 不把private val 当作private final val?有什么根本原因吗?

Why doesn't scalac just treat private val as private final val? Is there any underlying reason?

推荐答案

所以,这只是一个猜测,但在 Java 中,最终静态变量在右侧带有文字的内联到字节码中是一个长期的烦恼作为常数.这肯定会产生性能优势,但如果常量"发生变化,则会导致定义的二进制兼容性中断.在定义其值可能需要更改的最终静态变量时,Java 程序员必须求助于诸如使用方法或构造函数初始化值之类的技巧.

So, this is just a guess, but it was a perennial annoyance in Java that final static variables with a literal on the right-hand side get inlined into bytecode as constants. That engenders a performance benefit sure, but it causes binary compatibility of the definition to break if the "constant" ever changed. When defining a final static variable whose value might need to change, Java programmers have to resort to hacks like initializing the value with a method or constructor.

Scala 中的 val 已经是 Java 意义上的 final.看起来 Scala 的设计者正在使用冗余修饰符 final 来表示允许内联常量值".所以 Scala 程序员可以完全控制这种行为,而无需求助于黑客:如果他们想要一个内联常量,一个永远不会改变但很快的值,他们写最终 val".如果他们希望在不破坏二进制兼容性的情况下灵活地更改值,只需val"即可.

A val in Scala is already final in the Java sense. It looks like Scala's designers are using the redundant modifier final to mean "permission to inline the constant value". So Scala programmers have complete control over this behavior without resorting to hacks: if they want an inlined constant, a value that should never change but is fast, they write "final val". if they want flexibility to change the value without breaking binary compatibility, just "val".

这篇关于为什么`private val` 和`private final val` 不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆