【问题标题】:How is this private variable accessible?这个私有变量如何访问?
【发布时间】:2015-02-13 11:06:01
【问题描述】:

当我编写以下代码时,编译器如何不报错?

public class MyClass 
{
    private int count;

    public MyClass(int x){
        this.count=x;
    }

    public void testPrivate(MyClass o){
        System.out.println(o.count);
    }   
}

即使它是编写testPrivate 的同一类的实例,它不应该在System.out.println(o.count) 处给出编译错误吗?毕竟,我正在尝试直接访问私有变量。
代码甚至运行良好。

【问题讨论】:

  • Class MyClass知道count变量,所以没问题
  • 它是类私有的,而不是实例私有的。 Java 不会试图阻止你的左手碰到你的右手。 ;)
  • 通过 Eclipse 或 IDEA hashCode 和 equals 方法生成,它们总是这样
  • @PeterLawrey 是的,但我的印象是,如果我什至尝试访问私有,编译器会打我的头;但它是班级私有的,这是有道理的。谢谢
  • @KanwaljeetSingh 令人惊讶的是,如果您在嵌套类中有私有字段/方法/构造函数,您仍然可以在同一个外部类的另一个嵌套类中访问它。

标签: java private


【解决方案1】:

可以从声明它的类中的任何方法访问私有成员,无论该方法是访问其自己 (this) 实例的私有成员还是某个其他实例的私有成员。

这是在JLS 6.6.1:

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

Java 的这一特性允许您编写接受类实例作为参数的方法(例如 - clone(Object other)compareTo(Object other)),而无需依赖具有非私有 getter 的类来获取所有需要的私有属性被访问。

【讨论】:

  • TBH,我并没有意识到这一点,但它确实被明确列为我办公桌上 Java 大部头的私有警告(Hansen Krüger 第 200 页的清单 9.6:“Handbuch der Java-Programmierung”,Addison-Wesley,2012)。在 Venners 的“Inside the JAVA Virtual Machine”中乍一看并没有提及。感谢您的问题和答案。
  • 谢谢,现在说得通了。我一直将compareToequals 与吸气剂一起使用。当我注意到我们也可以在没有 getter 的情况下访问它时,这很奇怪。
【解决方案2】:

私有字段是整个类的私有字段,而不仅仅是对象。

其他类不知道MyClass有一个叫count的字段;但是,一个 MyClass 对象知道另一个 MyClass 对象具有 count 字段。

【讨论】:

  • 很好的补充,只是我需要的解释
【解决方案3】:

访问器不是安全的!它们是封装,以防止其他人知道代码。

考虑一下,如果有人写了一个Quantum Bogo Sort,但在他消除了最后一个错误后就消失了——理解代码会导致一个人要么被从宇宙中删除,要么发疯。

尽管有这个小缺点,但如果封装得当,这应该会成为您首选的排序算法,因为除了 Sort 之外的所有字段和方法都应该是私有的。

你不知道它是如何工作的,你也不想知道它是如何工作的,但它是有效的,这就足够了。另一方面,如果所有内容都是公开的,并且您必须了解它是如何正确使用它的——这太麻烦了,我会坚持使用快速排序。

【讨论】:

    【解决方案4】:

    虽然它是 testPrivate 所在类的实例 写的,但不应该通过编译器错误 System.out.println(o.count);

    。它永远不会抛出编译错误。

    这与简单的 getter 和 setter 或复制构造函数非常相似。请记住,我们可以使用this. 访问private 成员

    public MyClass {
      private String propertyOne;
      private String propertyTwo;
    
      // cannot access otherObject private members directly
      // so we use getters
      // But MyClass private members are accessible using this.
      public MyClass(OtherClass otherObject) {
          this.propertyOne = otherObject.getPropertyOne();
          this.propertyTwo = otherObject.calculatePropertyTwo();
      }
    
      public void setPropertyOne(String propertyOne) {
          this.propertyOne = propertyOne;
      }
    
      public String getPropertyOne() {
          return this.propertyOne;
      }
    }
    

    您的 testPrivate 方法接受 MyClass 的实例。由于testPrivateMyClass 内部的一个方法,它可以访问private 属性。

      public void testPrivate(MyClass o) {
          this.propertyOne = o.propertOne;
      }
    

    类中定义的方法将始终可以通过this. 和实例变量访问它的private 成员。

    但如果您在MyClass 之外定义testPrivate,那么您将无法访问private 成员。在那里,您将不得不使用方法、setter 或 getter。

    【讨论】:

      【解决方案5】:

      声明为私有的方法、变量和构造函数只能在声明的类本身内访问。检查official documentation

      【讨论】:

        猜你喜欢
        • 2011-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多