【问题标题】:Inner class object内部类对象
【发布时间】:2020-09-18 22:16:55
【问题描述】:

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

我的期望是它应该在两个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; }
    }
}

【问题讨论】:

  • 您的MyInner 可以访问MyOuter 类的两个 不同实例,一个是外部类,可以使用MyOuter.this 访问,一个是基类,可使用super 访问。 innerObj.getX() 调用继承自基类的getX() 方法。似乎不合格的x 访问了MyOuter.this 实例。为了使您的代码任何有意义,请删除extends Outer
  • 仅供参考: 我是一位经验丰富的 Java 程序员,但如果您问我是否可以通过非限定访问访问 super 实例或 MyOuter.this 实例,我需要查阅手册来回答这个问题。拥有与外部类和基类相同的类是错误的,在现实生活中永远不应该发生。如果是这样,那么代码应该总是限定字段访问,以确保每个人都理解代码在做什么。如果编译器失败并显示“ambiguois access”错误消息,我会更喜欢。
  • @Turing85 LOL,我们同时互相评论。我错过了private 部分。 --- 好奇:在今天之前,如果字段不是private,您是否能够回答对x 的无资格访问是指super.x 还是MyOuter.this.x?跨度>

标签: java inner-classes


【解决方案1】:

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

  • 一个字段super.x继承自MyOuter,但由于声明为private而无法访问,而MyInner作为继承对象无法访问该字段。
  • sorrounding MyOuter-instance 中的一个字段MyOuter.this.x(因为MyInner 是一个(非静态)内部类,它始终绑定到周围@987654332 的实例@),这是可访问的。

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

调用innerObj.getX()(继承自MyOuter,可以访问super.x)返回被继承的字段super.x的值(仍然是初始值3)。

如果我们从MyInner 中删除extends MyOuter 并将getX() 方法包含在MyInner 中,则代码将按预期运行。


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

【讨论】:

  • 啊,private,我错过了那个细节,这就是为什么x = 100 表示MyOuter.this.x = 100,而不是super.x = 100。如果你删除privatex = 100 突然变成super.x = 100。为了完整起见,您可能也想在答案中涵盖这一点。含糊不清,super 胜过外部类访问,这确实有道理,但仍然......
  • @Andreas 啊我忘记了MyOuter.this... 的语法。更新了我的答案。感谢您的评论!
  • Nitpick: "nonstatic, inner class" --- Inner classes are by definition non-static: "Inner class is an nested class that is not显式或隐式声明static"。 --- 但是,提醒人们是可以的,所以离开它......我的强迫症已经对这个评论感到满意。 ?‍♂️
  • @Andreas 我知道 ;) 但尤其是在答案中,我想澄清这种情况。把它放在括号里:)
猜你喜欢
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多