jerry
jerry

Reputation: 355

Scala constructor parameter modifiers

I would like to clarify some concepts in scala

class Test(a:Int) {
 def print = println(a)
}

class Test1(val a:Int) {
 def print = println(a)
}

class Test2(private val a:Int) {
 def print = println(a)
}

val test = new Test(1)
val test1 = new Test1(1)
val test2 = new Test2(1)

Now when I try to access a in test, test1, test2.

Scala prints

scala> test.a
<console>:11: error: value a is not a member of Test

scala> test1.a
res5: Int = 1

scala> test2.a
<console>:10: error: value a cannot be accessed in Test2

I understand Integer a is a field of Test1 and Test2. But what is the relationship of Integer a and class Test? Apparently Integer a is not a field of class Test, but it is accessable in print function.

Upvotes: 5

Views: 754

Answers (1)

Paul Butcher
Paul Butcher

Reputation: 10852

The best way to see what's going on is to decompile the resulting Java classes. Here they are:

public class Test
{
  private final int a;

  public void print()
  {
    Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.a));
  }

  public Test(int a)
  {
  }
}

public class Test1
{
  private final int a;

  public int a()
  {
    return this.a; } 
  public void print() { Predef..MODULE$.println(BoxesRunTime.boxToInteger(a())); }


  public Test1(int a)
  {
  }
}

public class Test2
{
  private final int a;

  private int a()
  {
    return this.a; } 
  public void print() { Predef..MODULE$.println(BoxesRunTime.boxToInteger(a())); }


  public Test2(int a)
  {
  }
}

As you can see, in each case a becomes a private final int member variable. The only difference is in what kind of accessor is generated. In the first case, no accessor is generated, in the second a public accessor is generated and in the third it's private.

Upvotes: 7

Related Questions