5

I know that a val is not final unless explicitly declared so and using javap confirms that Scalac is not inserting finalinto the bytecode.

So is a val immutable simply because the compiler stops us from writing any code that attempts to mutate it?

JamieP
  • 1,664
  • 2
  • 13
  • 16

1 Answers1

9

final and immutability are two orthogonal concepts:

val means you can't change (mutate) a variable by assigning anything to it after initial declaration:

val x = 1
x = 2 // error: reassignment to val

In JVM bytecode it's implemented by creating a private member and a getter, but not setter:

class A {
  val x = 1
}

=>

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

final means you can't override your val in a subclass:

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

final will cause the same error if you use var instead of val.

Victor Moroz
  • 9,167
  • 1
  • 19
  • 23
  • Unfortunately, Java conflates these uses of final so anyone coming from Java is likely to be confused at first. – Phasmid Oct 03 '16 at 17:54
  • @Victor, thanks for the comment. So putting my confusion of the application of `final` to one side, are you answering my question about how `val` is an immutable construct because scalac will not allow us to implement a `setter` for the `val`? – JamieP Oct 03 '16 at 18:54
  • Scalac itself does not implement a setter for the val. So it is effectively immutable. Even Java's final fields can be mutated with reflection if you try hard enough. – Jasper-M Oct 03 '16 at 19:05
  • @JamieP `val` is immutable because scalac treats it as such, technically it has nothing to do with JVM (unless you call Scala from Java). I only mentioned Java equivalent because it illustrates the concept from Java's point of view. – Victor Moroz Oct 03 '16 at 19:30