2011-10-27 53 views
9

我碰到下面的「奇怪」的功能今天來 - 如果你有從A級的A級機體對象的引用,你可以訪問這個對象的私人領域 - 即:有私人字段訪問時可以有參考嗎?

public class Foo{ 
    private int bar; 
    private Foo foo; 
    public void f() 
    { 
     if(foo.bar == bar) // foo.bar is visible here?! 
     { 
      // 
     } 
    } 
} 

任何人都有很好的解釋嗎?

+2

當你必須編寫一個equals方法時,這個特性非常有用。 –

+2

同樣的問題:http://stackoverflow.com/questions/2126984/why-is-the-access-to-a-private-field-not-forbidden,http://stackoverflow.com/questions/4340129/accessing -private-field-in-java,http://stackoverflow.com/questions/312168/java-private-field-visibility –

回答

19

訪問修飾符在類級而非實例級工作:同一類中的所有代碼都可以訪問類的所有實例的私有成員。

沒什麼特別奇怪的。

3

由於f()是Foo的成員,因此它有權訪問Foo的私有成員。這對我來說並不奇怪。

+0

這就是爲什麼當foo是Foo類和bar的另一個實例時我們可以訪問foo.bar是一個私人領域 – asenovm

+1

@iLate:因爲這是指定語言的方式...... –

+0

@iLate:我猜設計師只是遵循C++的行爲。 – LLS

0

因爲私人並不意味着它是私人的,而是來自其他類的私人。你在Foo裏面,因此你可以看到酒吧。

這樣做私有的構造在單身等

0

這些關鍵字類的面向工作的,不是面向對象的。所以它只是看起來和看到「噢,Foo類的一個對象試圖訪問Foo上的私有對象,那很好」。

5

它的目的是這樣。

引述Java Language Specification:基準的

甲構件(類,接口,字段或方法)(類,接口,或陣列)型或類型的構造是可訪問僅當類型和訪問的成員或構造被聲明爲允許訪問:

  • ...
  • (否則,)如果成員或構造函數聲明爲private,則只有當內發生其訪問被允許,如果和頂層cla的身體ss(§7.6)包含成員的聲明。
  • ...
+2

+1爲JLS參考。 –

1

這是有道理的,如果你考慮到「私人」修飾符打算隱藏實現細節。

試着用「這個對這個類應該是私有的」(在Java中等於「這應該是這個源文件的私有的」)而不是「這應該是這個實例的私有的」來思考它。

0

@Michael的回答是正確的。對於@asenovm的代碼,.NET的行爲是相同的。

此外,對於內部類以及Java也是如此。即使您將變量定義爲私有,您也可以訪問它。當我第一次遇到我時感到驚訝,因爲它與C#不同。

public class WrapperClass 
{ 

    public static class NotThreadsafe { 
     private int x = 0; 
     //....   
    } 

    public static void main(String[] args) {   
    final NotThreadsafe nts=new NotThreadsafe(); 
    int x = nts.x ; // !!! THIS IS ACCESSIBLE AS WELL FOR JAVA BUT NOT.NET 
    } 
} 

這與C#嵌套類不相同。如果您將此代碼粘貼到Visual Studio中,則不起作用。編譯器對訪問級別很感興趣。