2013-08-29 183 views
2

爲什麼內部類可以訪問這樣的類的輸入對象參數的私有字段?內部類方法和私有字段

private class Inner { 
    private int privatefield = 0; 

    public void method(Inner inner) { 
     privatefield = 1; //ok 
     inner.privatefield = 1; //this line confusing me (broken incapsulation) 
    } 
} 
+0

如果它是私密的,一個類可以訪問該屬性。包,子類或整體世界中沒有任何東西,但同一類中的所有東西都沒有。 http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html – Joetjah

+0

所以任何內部類的私有字段都是外部類的字段(沒有訪問限制)。但它是中斷封裝。在我看來,我應該只能訪問外部字段和內部類字段,而不能訪問另一個內部類實例的字段。 – pswrdf

+0

第一種情況在這裏解釋:[鏈接](http://stackoverflow.com/a/17027518/2728393) – pswrdf

回答

5

這與內部類本身無關。

中的代碼總是可以訪問Java中同一類的私有成員。 private/public等的概念是指代碼所在的位置,而不是指它是指「這個」實例還是另一個實例。受保護的訪問比其他訪問稍微複雜一些,但同樣的一般原則適用。

查看JLS section 6.6瞭解更多詳情。特別是:

否則,如果成員或構造函數被聲明爲私有的,那麼當且僅當它出現在包含成員聲明的頂級類(§7.6)構造函數。

這就解釋了爲什麼一個嵌套類可以訪問另一個嵌套類的私有字段,只要它們嵌套在同一個頂級類中,就像你的註釋一樣。這是一條奇怪的規則,我同意 - 我更喜歡C#的方法private可訪問性和嵌套類型 - 但上面的報價顯示編譯器服從JLS的規則。

我懷疑是因爲如果你在同一個頂級類中工作,你要負責該類中的所有代碼,包括嵌套類 - 所以你信任不會濫用它們。

+0

你的意思是內部類與外部類是相同的類? – pswrdf

+0

@pswrdf:不,但是您顯示的所有代碼都與'Inner'有關。你的代碼在'Inner'中,它指的是一個'Inner'的實例 - 所以它可以訪問私有字段。 –

+0

因此,如果您將使用與Inner相同級別的其他課程,您也可以訪問。例如:'private class Inner {void method(Inner2 inner2)....} private class Inner2 {}' – pswrdf

0

爲什麼內部類可以訪問這些類的輸入對象特性參數的私人領域?

  • 即使private,內部類是外類的成員
  • private成員的類的成員訪問。
0

考慮到你的班級既不嵌套也不嵌套private,因爲它與你的問題無關。它與示波器可視性有關。

Declaration says

private修飾符 - 場僅僅存在於自己類是訪問。

既然你訪問一個聲明,即使它是一個不同的實例您的封裝不破的成員在類中的privatefield財產,private範圍保持不變。

0

類中的任何方法都可以訪問該類中的全局變量。 private參數只能使OTHER參數不能訪問變量。

在這種情況下,Inner中的方法將能夠找到var以及Inner以外的方法將無法訪問的方法。

0

由於method(Inner inner)駐留在Inner類中,因此method(Inner inner)可以訪問Inner類的私有成員。

0

訪問修飾符定義變量可以訪問的範圍,而不是個別實例是否可以訪問它!

private int privatefield = 0; 

你的變量是非靜態的,所以它將被類的實例訪問。所以inner.privatefield是有道理的。現在您的變量privatefieldprivate,這意味着您可以在您的Inner class中訪問它。由於您正在訪問位於Inner class內的method()內部的變量,因此不存在任何問題並且完全有效。