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

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

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

有人对此有一个很好的解释吗?

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

没什么特别奇怪的。

它就是这样的。

引用Java语言规范 :

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

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

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

如果您考虑“私有”修饰符的意图隐藏实现细节,这是有道理的。

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

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

这样私人建筑师可以在单身人士等工作。

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

@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,它将无效。 编译器困扰访问级别。