More Than Five
More Than Five

Reputation: 10419

Specifying val in constructor

In Scala I can write constructors as:

class Cons[T](head: T, tail: List[T]) {
...
}

or

class Cons[T](val head: T, val tail: List[T]) {
...
}

What's the difference?

Upvotes: 0

Views: 185

Answers (2)

axel22
axel22

Reputation: 32335

As the others said, the difference is that val will make the values publicly accessible with the exception of case classes that always treat the constructor parameter as a val.

Another more subtle difference is that val will make a field in the class, meaning that the reference to the parameter value will exist during the object lifetime.

This does not happen by default when you do not specify a val, but still can in case that you use the constructor argument in the class body outside of the constructor body. For example, a is used in the ctor body, so it won't be lifted into an object field below:

class A(a: Int) {
  println(a)
}

In the following example, a becomes a private field:

class A(a: Int) {
  def foo = a
}

because it is necessary to have after construction and during the object lifetime to be able to call foo.

One more place where this might implicitly happen even without referencing the parameters from the body of the class is when using specialization:

class Foo[@spec A](v: A) {
  var value: A = v
}

See the bytecode:

  public final A v;
    flags: ACC_PUBLIC, ACC_FINAL
    Signature: #12                          // TA;


  public A value;
    flags: ACC_PUBLIC
    Signature: #12                          // TA;

This was tested using 2.10.1 and it is possibly a bug in the specialization implementation.

Upvotes: 2

Ben James
Ben James

Reputation: 125119

Specifying val makes the property publically accessible. (This is the default behaviour for case class parameters, without requiring val.)

See Section 5.3 of the language spec.

Upvotes: 4

Related Questions