有引用时可以访问Java私有字段吗?

时间:2011-10-27 13:05:26

标签: java access-modifiers private-members

我今天遇到了以下“奇怪”的特征 - 如果您在A类主体中引用了A类中的对象,则可以访问该对象的私有字段 - 即:

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

任何人对此都有一个很好的解释?

7 个答案:

答案 0 :(得分:19)

访问修饰符在类级别而不是在实例级别工作:同一个类中的所有代码都可以访问该类的所有实例的私有成员。

没有什么特别奇怪的。

答案 1 :(得分:5)

意图是这样的。

引用Java Language Specification

  

引用(类,接口或数组)类型的成员(类,接口,字段或方法)或类类型的构造函数只有在类型可访问且成员或构造函数声明为允许访问:

     
      
  • ...
  •   
  • (否则,)如果成员或构造函数被声明为private,则当且仅当它发生在包含成员声明的顶级类(第7.6节)的主体内时才允许访问。
  •   
  • ...
  •   

答案 2 :(得分:3)

由于f()是Foo的成员,因此它有权访问Foo的私有成员。这对我来说并不意外。

答案 3 :(得分:1)

如果你考虑'private'修饰符的意图来隐藏实现细节,那就没有意义。

尝试用“这应该属于这个类的私有”(在Java中等同于“这应该是这个源文件的私有”)来考虑它,而不是“这应该对这个实例是私有的”。

答案 4 :(得分:0)

因为私有并不意味着私有来自Object之外,而是私有来自其他类。你在Foo里面,所以你可以看到吧。

这样私人构造函数可以在Singletons等中工作。

答案 5 :(得分:0)

这些关键字是面向类的,而不是面向对象的。所以它只是看起来并且看到“噢,Foo类的对象试图访问Foo上的私有对象。好吧,那很好。”

答案 6 :(得分:0)

@Michael的回答是正确的。 .NET代码@asenovm的行为相同。

此外,内部类也适用于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,它将无法正常工作。编译器困扰访问级别。