102

Scala Reference のセクション 4.1 を見るまでは、private valとは同じだと思っていました。private final val

定数値定義の形式は次のとおりです。

final val x = e

ここで、e は定数式です (§6.24)。final 修飾子が存在する必要があり、型注釈を指定することはできません。定数値 x への参照は、それ自体が定数式として扱われます。生成されたコードでは、定義の右辺 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 valis not private final val.

scalacが単に として扱わprivate valれないのはなぜprivate final valですか? 根本的な理由はありますか?

4

2 に答える 2

84

したがって、これは単なる推測ですが、Java では、右側にリテラルを持つ最終的な静的変数が定数としてバイトコードにインライン化されることは、長年の悩みの種でした。これは確かにパフォーマンス上の利点をもたらしますが、「定数」が変更された場合、定義のバイナリ互換性が失われます。値を変更する必要がある可能性のある最終的な静的変数を定義する場合、Java プログラマーは、メソッドまたはコンストラクターで値を初期化するなどのハックに頼る必要があります。

Scala の val は、Java の意味では既に final です。Scala の設計者は冗長な修飾子 final を使用して、「定数値をインライン化する許可」を意味しているようです。そのため、Scala プログラマーは、ハックに頼ることなくこの動作を完全に制御できます。インライン化された定数、つまり決して変更されるべきではないが高速な値が必要な場合は、"final val" と記述します。バイナリ互換性を損なうことなく値を変更する柔軟性が必要な場合は、「val」だけです。

于 2012-11-16T08:27:22.723 に答える
8

ここでの混乱は、不変性と final のセマンティクスを混同することから生じると思います。 vals は子クラスでオーバーライドできるため、明示的にマークしない限り、最終として扱うことはできません。

@Brian REPLは、行レベルでクラススコープを提供します。見る:

scala> $iw.getClass.getPackage
res0: Package = package $line3

scala> private val x = 5
<console>:5: error: value x cannot be accessed in object $iw
  lazy val $result = `x`

scala> private val x = 5; println(x);
5
于 2012-11-17T06:38:43.143 に答える