To research this question we can reverse engineer to see "what would the compiler do?" :)
For that, we are compiling the class C.scala
with the content
class C(x: Int){}
by running:
scalac C.scala
this, generates C.class
.
Now, we can use the java class disassembler javap to see what the compiler would generate.
running
javap -p C.class
would produce:
public class C {
public C(int);
}
if we are repeating the whole procedure with
class D(val x: Int){}
we would yield:
public class D {
private final int x;
public int x();
public D(int);
}
We can see that the difference is that the keyword val
is telling the class to create a getter method.
Coming back to your assumption that without the val
keyword the class variable would be defined as mutable: this is wrong. To prove that we can go one level deeper into the disassembling. By running:
javap -p -v C.class
we get (among a lot of other information) this snippet :
{
public C(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
0: aload_0
1: invokespecial #14 // Method java/lang/Object."<init>":()V
4: return
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LC;
0 5 1 x I
LineNumberTable:
line 4: 0
line 2: 4
MethodParameters:
Name Flags
x final
}
you can clearly see that the class variable x
is still declared as final
and thus, immutable.