2012-09-05 44 views

回答

2

只讀在C#和最終在Java或多或少是相同的(至少當它們被施加到字段)。無論何時將字段標記爲final,只要通過變量初始化或通過對象構造函數進行賦值,編譯器將不允許您修改其引用。

但是它不會阻止你改變你引用的對象的內容,做這樣的事情:

public class Person { 
    public final String name; 
    public final Address address; 

    public Person(String name, Address address) { 
     this.name = name; 
     this.address = address; 
    } 
} 

//Someplace else 
Person peter = new Person("peter", new Address("Dolphin Cove 993", "Stamford", "CT"); 
peter.address.state = "CA" 

這是即使在外地「地址」是最終完全有效。

此外,不要依賴最終建立任何類型的「安全」或強訪問限制的某些價值,因爲它可以很容易地通過反思破壞。 (http://stackoverflow.com/questions/4516381/changing-private-final-fields-via-reflection)

所有可能是不需要此澄清,但有人可能會發現它有用

乾杯, Claudio

7

這取決於你的意思是「OK」。您無法更改items.length的原因是length是隻讀字段;數組創建後,其大小是固定的。不管items是否被聲明爲final,您指定的「不允許」行都將失效。

明白,做一個items可變final只是意味着你將無法改變變量的值是指不同的排列是很重要的。變量值是參考,而不是陣列本身。你不能改變的變量是指陣列,但你仍然可以改變數組的內容:

// Entirely valid... 
items[0] = new Object(); 

如果你想要的東西,這是真正的不可變的,你不能使用數組。

+2

+1空數組是不可變的,但是一個或多個數組是可變的。 –

0

有些人更喜歡將所有實例變量保留爲私有的,並使用「getters」一個getLength()方法,但它確實是個人偏好。沒有確切的錯誤與公共最終字段;這只是風格。就個人而言,我有時候會用它們來進行非常簡單的課程

+0

如果public final字段持有對可變對象的引用,那麼它可能是錯誤的。在這種情況下,Getter返回不可變視圖或對象副本是唯一的方法。 – Rorick

+0

當然,但也可能出現這樣的情況,即封閉類與其他實例數據的引用完全相同,即使它是可變的。完全取決於用例。 –

0

當然,所以將它公開爲只讀的方式是將成員變量的「項目」隱藏在您的類中,並公開getter方法。類似:

public int getNumItems() { 
    return (items == null ? 0 : items.length); //includes null handling using ternary operator 
}