2009-10-12 61 views
3

此代碼爲什麼允許指向構造函數參數?

class Foo(str: String) { 
    val len = str.length 
    def getLen = len 
    def getStr = str} 

將被編譯到

public class Foo implements ScalaObject 
{ 

    private final int len; 
    private final String str; 
    public Foo(String str) 
    { 
     this.str = str; 
     super(); 
     len = str.length(); 
    } 

    public String getStr() 
    { 
     return str; 
    } 

    public int getLen() 
    { 
     return len(); 
    } 

    public int len() 
    { 
     return len; 
    } 

    public int $tag() 
     throws RemoteException 
    { 
     return scala.ScalaObject.class.$tag(this); 
    } 
} 

但這個代碼

class Foo(str: String) { 
    val len = str.length 
    def getLen = len 
} 

將被編譯到

public class Foo implements ScalaObject 
{ 

    private final int len; 

    public Foo(String str) 
    { 
     len = str.length(); 
    } 

    public int getLen() 
    { 
     return len(); 
    } 

    public int len() 
    { 
     return len; 
    } 

    public int $tag() 
     throws RemoteException 
    { 
     return scala.ScalaObject.class.$tag(this); 
    } 
} 

爲什麼沒有私人Foo班的成員?

private final String str; 

它是某種優化嗎?

爲什麼允許指向構造函數的參數。 爲什麼「def getStr = str」行沒有編譯時錯誤?

+0

+1今天早上我問自己同樣的事情:-)。 – helpermethod 2012-10-10 07:52:08

回答

1

那麼,根據Odersky的書,構造函數是唯一可以將字段與構造函數參數進行匹配的地方。如果你不這樣做,那麼在構造函數之外將不會看到變量。

3

在Scala中,構造函數參數在類中任何地方都可見,我更像是「對象參數」。在你的第二個代碼片段中,它沒有被編譯爲爲它創建一個類屬性,只是因爲你沒有在構造函數之外引用它 - 這是不需要的。

+0

但誰應該管理用作構造函數參數的對象的生命週期? – 2009-10-13 10:08:46

+0

我不確定我是否理解這個問題......當沒有參考文獻時,通常的對象可能是GC'd。您的Foo類不管理該對象的生命週期(它在其他地方被實例化,並且誰知道有多少引用在其周圍)。編譯只是確保在不需要時不要保留引用。這可能會或可能不會使其成爲GC候選人,取決於其他地方正在做些什麼。 – 2009-10-21 22:55:49

相關問題