2012-12-26 104 views
4

我想澄清斯卡拉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) 

一些概念現在,當我試圖訪問一個測試,TEST1,TEST2。

斯卡拉打印

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 

我明白了一個整數Test1的是和TEST2的領域。但Integer a和class Test有什麼關係?顯然整數a不是Test類的字段,但它在打印函數中是可訪問的。

+1

沒有'val'(或其他註釋),構造函數參數的行爲就像一個對所有嵌套的作用域都可見的函數參數。 (我不確定當前實現中發生了什麼奇妙的事情,但是我想象一個名字被破壞的字段。請看一下生成的Java類。) – 2012-12-26 22:59:41

回答

6

查看發生了什麼的最好方法是反編譯生成的Java類。在這裏,他們是:

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) 
    { 
    } 
} 

正如你所看到的,在每種情況下a成爲private final int成員變量。唯一的區別在於生成哪種訪問器。在第一種情況下,不生成訪問者,第二種情況下生成公共訪問者,第三種訪問者是私有訪問者。

+0

應該是'Predef.'是'Predef $'?使用'javap'似乎是後者,然而[JD-GUI](http://java.decompiler.free.fr/?q=jdgui)似乎會生成前者。 –

+0

我沒有注意到(我用JD-GUI來做這個反編譯)。我不知道爲什麼JD-GUI將它顯示爲'Predef.' –