Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java不清楚的结果_Java_Variables_Inheritance_Initialization_Overriding - Fatal编程技术网

Java不清楚的结果

Java不清楚的结果,java,variables,inheritance,initialization,overriding,Java,Variables,Inheritance,Initialization,Overriding,我定义了三类(A、B、C): 预期结果是:6 但程序返回:0 有人能解释一下结果吗? 非常感谢您的帮助。类C重写A.foo(),多态性甚至在Java的构造函数中也是活动的。因此,当我们在构建C的实例时,当A中的构造函数调用foo()时,实际调用的是C.foo() C.foo()依次打印出B.i,因此我们可能希望打印出6——但实例变量初始值设定项仅在超类构造函数之后执行,因此在执行点,B.i为0 基本上,构造函数的执行顺序是: 执行链式构造函数,或者显式地this(…)链接到同一类中的另一个构造

我定义了三类(A、B、C):

预期结果是:6 但程序返回:0

有人能解释一下结果吗?
非常感谢您的帮助。

C
重写
A.foo()
,多态性甚至在Java的构造函数中也是活动的。因此,当我们在构建
C
的实例时,当
A
中的构造函数调用
foo()
时,实际调用的是
C.foo()

C.foo()
依次打印出
B.i
,因此我们可能希望打印出
6
——但实例变量初始值设定项仅在超类构造函数之后执行,因此在执行点,
B.i
为0

基本上,构造函数的执行顺序是:

  • 执行链式构造函数,或者显式地
    this(…)
    链接到同一类中的另一个构造函数,或者显式地
    super(…)
    链接到超类中的构造函数,或者隐式地
    super()
    链接到超类中的无参数构造函数
  • 对于链接到超类构造函数的构造函数,执行变量初始值设定项
  • 在构造函数体中执行代码
重写代码以避免使用变量初始值设定项和变量阴影可以使这一点更清楚,同时仍然保持代码的等效性:

public class A {
  int ai;

  public A() {
    super();
    ai = 5;
    foo();
  }

  public void foo() {
    System.out.println(ai);
  }
}

class B extends A {
  int bi;

  public B() {
    super();
    bi = 6;
  }
}

class C extends B {
  int ci;

  public C() {
    super();
    ci = 7;
  }

  public void foo() {
    System.out.print(bi);
  }

  public static void main(String[] args) {
    C c = new C();
  }
}
另一方面,如果您首先将所有字段设置为私有字段,那么“变量隐藏”部分就不会起作用,这是我的建议。这就留下了从构造函数调用虚拟方法的问题,这通常是一个坏主意,因为期望对象在有机会完全初始化之前能够工作,并且变量初始值设定项执行的时间可能令人惊讶


如果避免从构造函数调用虚拟方法,即使变量初始值设定项的时间也变得无关紧要-至少几乎总是如此。

该变量从未在类A中初始化,因此它正在打印PRMIIVAL int的默认变量,即0。问题是,尽管在层次结构树上为构造函数调用了super,但构造函数并没有初始化i,这是在初始化过程中完成的,初始化发生在构造函数之后。

我不确定您期望的是什么-您的示例不会按原样运行,如果它确实运行,则不会执行任何操作

此示例返回“6”:


不是在构造函数之后-而是在调用超类构造函数之后编译的构造函数体的第一部分。OP的代码对我来说编译和运行得非常好,并打印0。代码打印06-构造函数对
foo()
的调用打印0。只有在打印6的构造函数之后调用
foo()
public class A {
  int ai;

  public A() {
    super();
    ai = 5;
    foo();
  }

  public void foo() {
    System.out.println(ai);
  }
}

class B extends A {
  int bi;

  public B() {
    super();
    bi = 6;
  }
}

class C extends B {
  int ci;

  public C() {
    super();
    ci = 7;
  }

  public void foo() {
    System.out.print(bi);
  }

  public static void main(String[] args) {
    C c = new C();
  }
}
public class A {
     int i = 5;
     public A() {
       foo();
     }
     public void foo() {
       System.out.println(i);
     }
     public static void main(String[] args) {
        C c = new C();
        c.foo ();
     }
}

class B extends A {
     int i = 6;
}

class C extends B {
     int i = 7;
     public void foo() {
        System.out.print(super.i);
     }
}