首页 > 解决方案 > Java中的变量阴影,多种情况静态/非静态

问题描述

我最近一直在学习 Java,我们正在处理程序输出、编译错误等。我自己尝试了不同的代码,我的实验中的一件事让我很困惑:首先,主要方法如下所示:

public static void main(String[] args){
     A a = new A();
     B b = new B();
     A ab = new B();

     System.out.println(a.a + " " + b.a + " " + ab.a);

}

现在我尝试了这些不同的版本:

//1
public class A {
  public static int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
  public static int a = 2;
   public B(){ a = 22;}
}
//------------
//2
public class A {
  public int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
  public static int a = 2;
   public B(){ a = 22;}
}
//--------------
//3
public class A {
  public static int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
   public B(){ a = 22;}
}
//-----------
//4
public class A {
  public int a = 1;
   public A() {
    a = 11;
   }
}
public class B extends A {
   public B(){ a = 22;}
}

输出如下:

  1. 11 22 11

  2. 11 22 11

3:11 22 22

  1. 22 22 22

虽然我可以理解输出 1 和 2,但输出 3 和 4 真的让我感到困惑。

对于 3:B 中的a = 22改变了 A 对象 ab 的值,因为 int a 没有在 B 中再次声明?

而对于 4:如果A 中的int a不是静态的,并且a是 A 类型的对象,为什么 aa 的值是 ba?当我将int a 设置为非静态时,4 中发生了什么?

提前致谢!

标签: javavariablesstaticoutputshadowing

解决方案


重要提示:案例 4 的答案是 11 22 22

情况 3:当 A ab = B() 执行 B 的构造函数时,在 A 中设置静态变量 a,使其值为 22。

情况4:A类和B类都有实例字段(a)(实际上B类从A类继承了这个属性)并且在构造时首先执行A类的构造函数,然后执行B类的构造函数,所以当我们有A时= B() A 类的第一个构造函数将变量 a 设置为 11,然后 B 类的构造函数将其设置为 22 子类中的静态字段不要覆盖父类中的静态字段,如果您隐藏父类中的静态字段访问静态结果不取决于对象本身的类型,而是取决于您用于访问该对象的引用类型,因此当您编写 A a = B() 时,如果 A 和 B 都具有静态字段 a,则aa 的结果是类 A 中的 a 而不是类 B 中的 a,因为您用于访问此处对象的引用类型是 A,而对象类型本身是 B。


推荐阅读