为什么允许访问另一个对象的私有字段?

8

最近,我观察到Java中访问私有字段的意外行为。考虑以下示例,它展示了这种行为:

public class A {

    private int i;  <-- private field!

    public A(int i) {
        this.i = i;
    }

    public void foo(A a) {
        System.out.println(this.i);  // 1. Accessing the own private field: good
        System.out.println(a.i);     // 2. Accessing private field of another object!
    }

    public static void main(String[] args) {
        (new A(5)).foo(new A(2));
    }
}

为什么我可以在 foo 方法中访问另一个类 A 的私有字段(第二种情况)?


请使用代码格式化来处理代码、输入/输出和结构化文档,例如HTML或XML。为此,请选择示例并单击消息发布/编辑表单上方的“{}”按钮。 - Andrew Thompson
3个回答

14

私有字段保护的是类,而不是实例。其主要目的是允许一个类独立于其API进行实现。将实例与自身隔离,或将实例的代码与同一类的静态代码保护起来是没有意义的。


@MarkoTopolnik 不是的。实际上,我甚至观察到人们更喜欢在看到用户图片时点赞。CW答案收集的点赞和采纳都较少(对于踩我不能确定)。如果你认为这不好,你可以修复它。 - Denys Séguret
@dystroy,我绝对没有理由认为它是不好的,只是非常不寻常。你是如何决定将其作为CW答案的?整个功能主要是为了防止利用漏洞,例如不断对答案进行小修改,以使其排在“最近活动”列表的顶部,希望获得更多关注和赞同。 - Marko Topolnik
@MarkoTopolnik 嗯,当我在一个简单的问题上回答时,感觉自己会因为是经验丰富的程序员中第一个回答而得到赞同和/或接受,我经常将我的答案标记为 CW。这也使其他用户更容易改进它。虽然我不会把它作为规则,也不会假装其他用户应该这样做。 - Denys Séguret

3

这是因为它们属于同一类。在Java中是允许的。

您将需要此访问权限用于许多目的。例如,在equals的实现中:

public class A {
  private int i;

  @override public boolean equals(Object obj){
     if(obj instanceof A){
        A a = (A) obj;
        return a.i == this.i; // Accessing the private field
     }else{
       return false
     }
  }
}

你不一定需要它,但使用它可以使访问变得更简洁。 - NilsH
@NoobUnChained:你所有的私有字段都有公共访问器吗?如果是这样,封装的意义在哪里? - Mohayemin

0

foo方法属于与变量i相同的类,允许这样的访问并不会有任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接