2016-10-03 51 views
4

我知道val不是final,除非明確聲明如此,並且使用javap確認Scalac沒有將final插入到字節碼中。val是不可變的?

因此,val是不可變的,因爲編譯器阻止我們編寫任何試圖改變它的代碼?

+1

請查看[this](http://stackoverflow.com/a/13428362/1263942)爲什麼'val's不是'final':它們可以被覆蓋 –

回答

8

final和永恆性是兩個正交的概念:

val意味着你無法通過初始宣佈後分配任何改變它(變異)的變量:

val x = 1 
x = 2 // error: reassignment to val 

在JVM字節碼它是由實施創建一個私有成員和一個getter,但沒有設定裝置:

class A { 
    val x = 1 
} 

=> 

// Java equivalent of a generated bytecode 
public class A { 
    private final int x; 
    public int x() { return x; } 
    ... 
} 

final意味着你可以」牛逼覆蓋您val在子類:如果你使用var代替val

class A { 
    final val x = 1 
} 

class B extends A { 
    override val x = 2 
} 

// error: overriding value x in class A of type Int(1); 
// value x cannot override final member 

final會導致同樣的錯誤。

+0

不幸的是,Java混淆了final的這些用法,所以任何人來自Java的起初可能會感到困惑。 – Phasmid

+0

@Victor,感謝您的評論。因此,把「final」應用混淆在一邊,你是否回答了我關於'val'是如何不可變的構造的問題,因爲scalac不允許我們爲'val'實現'setter'? – JamieP

+0

Scalac本身並沒有實現val的setter。所以它是有效的不變的。如果您足夠努力,甚至Java的最終字段都可以通過反射進行變異。 –

相關問題