2010-01-13 29 views
11

將實例變量作爲final是什麼意思?有一個實例變量作爲最終的點?

將變量設置爲靜態最終變量不是更好嗎?

如果它不能被任何對象改變,那麼它就像一個類(靜態)變量一樣,對嗎?

+0

http://renaud.waldura.com/doc/java/final-keyword.shtml – 2010-01-13 04:12:59

回答

20

都能跟得上。 static表示在班級的所有實例中都是相同的。 final表示它在初始分配後不可分配。所以兩個實例對於非靜態final變量可以有不同的值。

有很多原因可能導致你想做一個變量final;最好的之一就是清晰度。如果我讀了一個方法,並注意到foo是最終的,我不必擔心它下面的變化 - 因爲它不是;它不能。我可以對最終變量的代碼進行更多的更改,而不必擔心(「我是否在bar之前或之後更改foo的值,這是否重要?」),因爲我知道某些變量不會更改。它也將我的注意力集中在可能更改的變量上 - 而且它們是值得更多關注的變量。

+1

但是當您編寫該類時,不要爲最終實例變量賦值嗎?那麼這意味着所有對象都將使用該值並且不會改變?還是我錯了? – ajsie 2010-01-13 04:14:10

+5

不一定 - 它可以在構造函數中分配。 – danben 2010-01-13 04:15:45

1

它可以防止其他程序員從做愚蠢的事情,他們不應該嘗試做反正 ...

2

您可以爲其指定一個特定於該對象實例的值,這是靜態類變量無法做到的。

+0

所以你的意思是當我寫課程時,我只是宣佈它是最終的。當我實例化類並調用方法時,該方法將爲其分配一個值,該值不能更改? – ajsie 2010-01-13 04:16:02

+0

我認爲你需要在構造函數中賦值,否則編譯器會拋出一個錯誤。 – 2010-01-13 05:28:38

3

兩個原因:

1)從一流的設計視圖,它允許程序員依靠一個事實,即場不會因爲實例變化 - 所謂的「immutable object」。 Java教程說:

不可變對象在併發應用程序中特別有用。由於它們不能改變狀態,所以它們不能被線程干擾破壞或在不一致的狀態下觀察到。

不變對象是各種編程風格的基石,例如,純功能編程。

2)第二個原因是JVM優化。如果所有字段都是最終的,那麼JVM知道該對象的狀態不能被改變,因此它可以進行許多優化,例如,省略線程安全檢查等。

+1

@Ondra - JVM *可能(或不可能)優化final字段等事實是一個側面的問題。使用'final'的主要動機應該是讓你的代碼更健壯。 (並且記住這樣的建議,即微觀優化Java是一個糟糕的主意,因爲JIT編譯器如果不這樣做可以做得更好) – 2010-01-13 05:15:22

+0

@Stephen: 1)我介紹了final的「健壯」方面第二段。 2)使你的小數據對象不變是絕對不是微觀優化 - 它可以提供顯着的性能提升。 「不讓一個類不可改變的最常見原因之一是相信這樣做會損害性能。雖然有時候這是真的,但它通常不是 - 有時使用不可變對象有時很重要,也許令人驚訝的是,性能優勢。「 – 2010-01-13 05:55:16

4

我猜你的心思簡單的例子如:

private final int num = 3; 

,可以更好的寫法如下:

private static final int NUM = 3; 

然而,往往你必須引用是可變對象,並因此不能在類之間共享:

private final List<Node> children = new ArrayList<Children>(); 

或者,或在構造函數導出:

public final class MyThing { 
     private final String name; 
     public MyThing(String name) { 
      this.name = name; 
     } 
     [...] 
} 

注:final字段可以在構造(或實例初始化劑)被分配,而不僅僅是如聲明的一部分。

+0

你最後的例子顯示了一個'final'類。這與可變性無關,只會讓新手讀者感到困惑。 – 2010-01-13 05:08:37