【问题标题】:Why is the output different in the two cases?为什么两种情况下的输出不同?
【发布时间】:2015-11-27 19:52:47
【问题描述】:

为什么即使变量已被覆盖,在以下情况下输出也会不同?

public class A {
    int a = 500;

    void get() {
        System.out.println("a is " + this.a);
    }
}

public class B extends A {
    int a = 144;
}

public class mainmethod {
    public static void main(String args[]) {
        B ob = new B();
        System.out.println("a is " + ob.a);
        ob.get();
    }
}

【问题讨论】:

标签: java field shadowing member-hiding


【解决方案1】:

不存在被覆盖的变量。 B 实际上有 两个 名为 a 的实例变量:一个它声明,另一个它继承。看到这个:

B ob = new B();
System.out.println("B.a is " + ob.a);
System.out.println("A.a is " + ((A)ob).a);

在B 的实例方法中,您可以编写super.a 或((A)this).a 来访问父级的变量。

【讨论】:

  • 有趣的(而且对初学者来说相当混乱)部分是在 get() 中打印这个给你 B@XXX
  • 有点令人困惑,但也是正确的:B 拥有这两个变量,而且都是关于名称解析规则,您可以在没有资格的情况下访问这些规则。但底线是:不要这样做。
  • 但是在字节码的局部变量表中可以看到this的签名是LA
  • 当然,因为它是在A 中声明的。 this 的静态类型肯定是A。
  • this.a 正在基于this 发生变化,但this 将在A 中打印相同的内容^--^
【解决方案2】:

不,变量没有被覆盖。 ob.a 打印 B 类的 a 变量。 ob.get() 在 B 类中搜索 get 方法。当它没有到达那里时,它会搜索父类并执行它。

【讨论】:

    【解决方案3】:

    在执行ob.a 时,您会从ob 对象中获取变量int a,该对象是B 类的对象。

    但是,当您执行 ob.get(); 时,您正在从类 A 中调用 get() 方法,因为在 B 中没有 get(),正如您所写的那样,它使用 this.a,在这种情况下,这将是 A 类的 int a。

    【讨论】:

      猜你喜欢
      • 2017-09-22
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 2019-11-08
      相关资源
      最近更新 更多