Scala Constructor Parameters

12,137

Solution 1

Yes, there are two important differences. First for the easy one: constructor parameters without the var or val keywords are not mutable variables—their values can't be changed in the body of the class.

Even if we restrict ourselves to the val keyword, though, there's still a difference between private val and keyword-less parameters. Consider the following:

class Person(private val firstName: String, lastName: String)

If we look at the compiled class with javap -v Person, we'll see that it only has one field, for firstName. lastName is just a constructor parameter, which means it may be garbage-collected after the class is initialized, etc.

The compiler is smart enough to know when the value of lastName will be needed after initialization, and it will create a field for it in that case. Consider the following variation:

class Person(private val firstName: String, lastName: String) {
  def fullName = firstName + " " + lastName
}

The compiler can tell that it may need the value of lastName later, and if we check javap again we'll see that the class has two fields (note that if we'd defined fullName as a val instead of a def, it'd only have one field).

Lastly, note that if we make firstName object-private instead of class-private, it works exactly like a plain old keyword-less constructor parameter:

class Person(private[this] val firstName: String, lastName: String)

This works even with var instead of val:

class Person(private[this] var firstName: String, lastName: String)

Both of these classes will have no fields. See section 5.2 of the language specification for more details about object-private access.

Solution 2

as a supplement, if your class is a case class, all of the constructor parameters will be automatically public fields.

The compiler will complain about the private keyword if it exists, and for the parameters without val/var, no matter they are used or not in any defs, there will be public fields generated for them.

Share:
12,137

Related videos on Youtube

user2456976
Author by

user2456976

Updated on June 05, 2022

Comments

  • user2456976
    user2456976 almost 2 years

    What is the difference between a private var constructor parameter and a constructor parameter without val/var? Are they same in terms of scope/visibility?

    Ex:

    class Person(private var firstName:String, lastName:String)
    
  • RussAbbott
    RussAbbott over 10 years
    Are you saying that in situations such as the example with def fullName there is no difference between a private val and a keyword-less parameter?
  • Dmytro Mitin
    Dmytro Mitin almost 4 years
    @TravisBrown In 2.13.2 both class Person(private[this] val firstName: String) and class Person(firstName: String) generate field private[this] val firstName: String stackoverflow.com/a/62686327/5249621