[scala] ‘private val’과 ‘private final val’이 다른 이유는 무엇입니까?

나는 그렇게 생각하는 데 사용 private val하고 private final val난 스칼라 기준에서 4.1 절을 볼 때까지, 동일 :

상수 값 정의는 다음 형식입니다.

final val x = e

여기서 e는 상수 표현식 (§6.24)입니다. 최종 수정자가 있어야하며 유형 주석을 제공 할 수 없습니다. 상수 값 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 Reference가 말한 것과 같습니다 : private valis not private final val.

scalac 은 다음 private val과 같이 취급 하지 private final val않습니까? 근본적인 이유가 있습니까?



답변

따라서 이것은 추측 일 뿐이지 만 오른쪽에 리터럴이있는 최종 정적 변수가 상수로 바이트 코드에 인라인되는 것은 Java에서 계속되는 성가심이었습니다. 이로 인해 성능상의 이점이 확실히 발생하지만 “상수”가 변경되면 정의의 이진 호환성이 깨집니다. 값을 변경해야하는 최종 정적 변수를 정의 할 때 Java 프로그래머는 메서드 또는 생성자로 값을 초기화하는 것과 같은 해킹에 의존해야합니다.

Scala의 val은 Java 의미에서 이미 최종입니다. Scala의 디자이너는 “상수 값을 인라인 할 수있는 권한”을 의미하기 위해 중복 수정 자 final을 사용하는 것 같습니다. 따라서 Scala 프로그래머는 해킹에 의존하지 않고도이 동작을 완벽하게 제어 할 수 있습니다. 인라인 상수, 절대 변경되지 않아야하지만 빠른 값을 원하면 “final val”을 작성합니다. 바이너리 호환성을 깨지 않고 값을 유연하게 변경하려면 “val”만 있으면됩니다.


답변

여기서 혼동은 불변성과 최종의 의미를 결합하는 데서 발생한다고 생각합니다. vals는 자식 클래스에서 재정의 될 수 있으므로 명시 적으로 표시되지 않는 한 final로 처리 될 수 없습니다.

@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


답변