What does final
mean for Scala constructor arguments? I have this example:
class IntFinalTest(
val intVal: Int,
final val finalIntVal: Int,
var intVar: Int,
final var finalIntVar: Int) {
// intVal = 3 // error: reassignment to val
// finalIntVal = 3 // error: reassignment to val
intVar = 3
finalIntVar = 3
}
class ArrayFinalTest(
val arrayVal: Array[Int],
final val finalArrayVal: Array[Int],
var arrayVar: Array[Int],
final var finalArrayVar: Array[Int]) {
arrayVal(0) = 3
finalArrayVal(0) = 3
arrayVar(0) = 3
finalArrayVar(0) = 3
}
Judging by the compiler output (only the two marked lines result in an error), there is no difference between final
and non-final
val
s and var
s - is this correct? I have verified by running this example that all variables except for intVal
and finalIntVal
do get modified.
Related question RQ1: Does final
have any significance in constructors of classes that are part of a hierarchy?
Related question RQ2: How do I create an immutable Array[Int]
class member if it's part of constructor argument list?
Context: I use Scala 2.10.5 and only have a few months of experience with it.
A val
cannot be changed. A val
can however be overridden, so even if you see a val
somewhere, you can't know its value for sure. (In the general case, it is hard to tell whether a member is overridden or not. This is known as Class Hierarchy Analysis and is equivalent to solving the Halting Problem.)
A final val
, however cannot be changed and cannot be overridden, so you know that its value can never be different than the one it was initialized with. Constructor parameters which are annotated with var
or val
become members of the class, and so final val
for a constructor parameter really means more or less the same thing as it does for a "normal" class/trait/object member.
Note that for (non-constructor) members declared exactly like this:
final val foo = e
i.e. with an explicit final
modifier (even if the val
were otherwise implicitly final, e.g. because it is inside a final
class or inside an object
), without a type annotation, and where e
is a constant expression, the declaration becomes a constant value declaration which the Scala Language Specification guarantees to be optimized by the compiler.