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

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

问题描述

我曾经认为private valprivate final val是相同的,直到我在Scala参考中看到了第4.1节:

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

常量值的定义形式为

A constant value definition is of the form

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参考中所说的那样: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.

就Java而言,Scala中的val已经是最终的了.看起来Scala的设计师正在使用多余的修饰符final表示允许内联常数".因此,Scala程序员可以完全控制这种行为,而无需求助于骇客:如果他们想要一个内联的常数(一个永远不变但很快的值),他们会写"final 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天全站免登陆