I'm still pretty new to Scala, but I know you can define class variables that are initialized in the constructor like
class AClass(aVal: String)
which would be like doing the following in java
class AClass {
private String aVal;
public AClass(String aVal) {
this.aVal = aVal;
}
}
In Java, I would declare aVal as final. Is there a way to make the aVal variable final in the Scala syntax?
EDIT: Here is what I am seeing when I compile the following Scala class:
class AClass(aVal: String) {
def printVal() {
println(aVal)
}
}
I ran javap -private
and got the output
public class AClass extends java.lang.Object implements scala.ScalaObject{
private final java.lang.String aVal;
public void printVal();
public AClass(java.lang.String);
}
When I change the scala class definition to have class AClass(**val** aVal: String)
I get the following output from javap -private
public class AClass extends java.lang.Object implements scala.ScalaObject{
private final java.lang.String aVal;
public java.lang.String aVal();
public void printVal();
public AClass(java.lang.String);
}
The public method aVal
is generated. I'm still learning here - can anyone explain why that is generated?
Note I am using scala 2.9
Copied from my answer: Scala final vs val for concurrency visibility
There are two meanings of the term
final
: a) for Scala fields/methods and Java methods it means "cannot be overridded in a subclass" and b) for Java fields and in JVM bytecode it means "the field must be initialized in the constructor and cannot be reassigned".Class parameters marked with
val
(or, equivalently, case class parameters without a modifier) are indeed final in second sense, and hence thread safe.Here's proof:
Or with
javap
, which can be conveniently run from the REPL:If the class parameter of a non-case class is not marked as a
val
orvar
, and it is not referred to from any methods, it need only be visible to the constructor of the class. The Scala compiler is then free to optimize the field away from the bytecode. In Scala 2.9.1, this appears to work:In this code, aVal is a final variable. So You already have a final variable.
In this code, aVal is final and you have getter of aVAl. So you can use it like below
And finally,
In this code, aVal is not final and you have getter and setter of aVal. So you can use it like below