2016-12-27 73 views
-1

我是新來的Java,我想知道爲什麼可以通過這種方式設置私有屬性的值,而不使用setter? :爲什麼我可以用Java中的getter設置私有類屬性的值?

class Example { 
    private int[] thing; 
    public void initialize() { 
     thing = new int[10]; 
    } 
    public int[] getThing() { 
     return thing; 
    } 
} 
class myclass { 
    public static void main(String args[]) { 
     Example e = new Example(); 
     e.initialize(); 
     e.getThing()[0] = 1; 
     System.out.println(e.getThing()[0]) // value is still 1... 
} 

我真的不明白爲什麼這是合法的......

編輯:我預計e.getThing()返回的東西價值不哪怕是給一點參考,案件,因爲「事物」是私人的,我認爲我不能直接修改它。

+0

你確定你將值設置爲**其他類的**私有成員嗎? –

+5

你期待什麼? – AxelH

+0

如果你想讓事情只讀,我會以兩種方式之一來做到這一點。 1)製作一個數組的防禦副本,其中我用'new'創建另一個數組並返回這個數組。 2)使用列表(例如,ArrayList ),並返回一個'Iterable'(這是一個由所有列表實現的接口)。唯一可以用'Iterable'完成的事情或多或少迭代(儘管如果它們是聚合,可以修改迭代中的對象)。 – patrik

回答

8

你正在暴露對來自getter的數組的引用,並且數組內容本身是mutable即你可以改變它們。因此,在上面的示例中,您返回對類中私有變量所擁有的數組的引用,您將修改該數組,並且該更改將通過前進的getter進行可視化,因爲它始終返回修改後的數組。

爲了避免這種情況,你可能要麼是:

  1. 回報通過您的getter一個集合的只讀視圖。這可能會很快,但是如果父對象在您(例如)迭代時更改了陣列內容,那麼這可能會令您感到困惑
  2. 通過您的獲得者返回防禦副本。這意味着返回一個新的數組每次通話複製,而這將不屬於你而改變,但是你在上面複製它爲每個呼叫

在你具體例子付出代價,你可以創建一個讀 - 只收集你的initialize()方法,然後你就不會有這個問題。

我覺得你需要清楚一點。 私人(即參考變量在課堂以外不可用)和可變(您返回的對象可以更改)。這是兩個非常不同的概念。

+3

Downvoted爲什麼? –

+0

thx。我認爲e.getThing()會返回值的東西,而不是它在內存中的引用,以便直接修改它,最終繞過任何setter。 – erebos007

2
private int[] thing; 

說,參考thing是私有的,爲此,不能從類的外部訪問。幸運的是,你有一個getter,所以你可以獲得參考。

由於數組是可變的,所以可以修改數組的內容。

不能做的是設置新thing

e.thing = new int[5]; 

,這是什麼私人一樣。

+0

你還沒有解釋爲什麼'initialize'能夠給變量賦值,即使從另一個類調用時也是如此。這就是問題所在。 – nvioli

+0

我不是,是嗎? –

+0

@BrianAgnew你是什麼意思? – xenteros

-2

事實上,thing是私有意味着你不能

Example e = new Example(); 
e.thing = new int[10]; 

但是,您選擇暴露initialize公開,這樣你就可以從另一個類調用它。 initialize的實現細節僅對Example類的作者是可知的。作者可以在該課堂中做他或她想做的任何事情,包括通過private字段做他或她想要的任何事情。

+0

對不起,我誤讀了那部分。 – lexicore

+0

你還沒有提出這個問題。 – lexicore

+0

我以爲混淆是關於從課外設置「私人」領域的能力,這就是我的回答;也許我誤解了OP的困惑。 – nvioli

0

這是因爲私人成員只能在他們定義的類中直接訪問,除非您提供一些公共訪問方法,否則無法在類之外訪問它們。你正在提供一個數組引用的公共存取器,並且在得到引用後你正在改變這個值

相關問題