val是如何不可变的?

Jam*_*ieP 4 scala

我知道,val是不是final,除非显式声明所以并使用javap的确认Scalac没有插入final到字节码.

val因为编译器阻止我们编写任何试图改变它的代码,所以是不可变的吗?

Vic*_*roz 8

final 和不变性是两个正交的概念:

val 意味着你不能通过在初始声明后为它赋予任何东西来改变(变异)变量:

val x = 1
x = 2 // error: reassignment to val
Run Code Online (Sandbox Code Playgroud)

在JVM字节码中,它是通过创建私有成员和getter来实现的,但不是setter:

class A {
  val x = 1
}

=>

// Java equivalent of a generated bytecode
public class A {
  private final int x;
  public int x() { return x; }
  ...
}
Run Code Online (Sandbox Code Playgroud)

final意味着你不能覆盖你val的子类:

class A {
  final val x = 1
}

class B extends A { 
  override val x = 2
}

// error: overriding value x in class A of type Int(1);
//  value x cannot override final member
Run Code Online (Sandbox Code Playgroud)

final如果您使用var而不是将导致相同的错误val.