首页 > 解决方案 > 内部类对象

问题描述

我无法理解以下代码的行为。

我的期望是它应该在这两种println()方法中打印 100。为什么结果不一样?

如果我getX()在内部类中取消注释方法,则println() 方法的输出相同,即 100。

我无法弄清楚不同行为的原因。请帮我理解。

public class Foo {

    public static void main(String[] args) {
        MyOuter outerObj = new MyOuter();
        MyOuter.MyInner innerObj = outerObj.new MyInner();

        innerObj.setX();

        System.out.println("x: " + innerObj.getX()); //x: 3
        System.out.println("x: " + outerObj.getX()); //x: 100
    }
}
class MyOuter {
    private int x = 3;

    public int getX() { return x; }

    class MyInner extends MyOuter {
        public void setX(){ x = 100; }
//      public int getX() { return x; }
    }
}

标签: javainner-classes

解决方案


MyInner的角度来看,这里有两个private int x领域在起作用:

  • super.x继承自 的一个字段MyOuter,但由于被声明为 而无法访问private,并且MyInner作为继承对象无法访问此字段。
  • MyOuter.this.x来自sorrounding MyOuter -instance的一个字段(因为MyInner是(非静态)内部类,它总是绑定到环境的实例MyOuter),这是可访问的。

setX()中的方法MyInner无法访问继承的字段super.x,因此它访问该字段MyOuter.this.x并将其值设置为100。对周围MyOuter的连续呼叫getX()将返回100

调用innerObj.getX()(从 继承MyOuter并可以访问super.x)返回继承字段的值super.x(仍然具有其初始值3)。

如果我们删除extends MyOuterfrom 并将getX()-method包含在 中MyInner,则代码将按预期运行。


MyInner无法访问继承字段的事实private x起初令人困惑,但该行为实际上与Hariharan在这篇文章中讨论的protected继承类中静态方法的上下文中关键字的行为一致


推荐阅读