【问题标题】:How is a constructor executed?构造函数是如何执行的?
【发布时间】:2021-11-14 10:14:09
【问题描述】:

我正在对讲座幻灯片进行一些修改,它说构造函数以下列方式执行:

  1. 如果构造函数以this开头,则递归执行指定的构造函数,然后转到步骤4。

  2. 调用显式或隐式指示的超类构造函数(除非此类为java.lang.Object)。

  3. 按照在此类中声明的顺序初始化对象的字段。

  4. 执行此构造函数的其余部分。

我不明白的是,构造函数永远不能以此“开始”,因为即使它没有形成类层次结构/关系,也会默认插入 super()。

这与上面的描述有什么关系?

【问题讨论】:

  • 请加上步骤编号,否则很难猜出“步骤4”是什么意思。

标签: java jvm initialization


【解决方案1】:

构造函数(对于除 java.lang.Object 之外的每个类)必须以“super()”开头,以调用其超类的构造函数,或以“this()”开头,以调用同一类的另一个构造函数。如果您的构造函数中没有包含其中任何一个,编译器将插入对 super() 的调用。构造函数可以从调用同一个类中的另一个构造函数开始,只要最终调用类中的构造函数并调用超类构造函数。

【讨论】:

    【解决方案2】:

    我不认为你是对的,或者我不明白这个问题。来自Java Language Spec

    如果构造函数体不是以显式构造函数开头 调用和构造函数是 声明不是原始的一部分 类 Object,然后是构造函数 身体被隐含地假定为 编译器从超​​类开始 构造函数调用“super();”,一个 调用其构造函数 不需要的直接超类 论据。

    因此,构造函数可以以this(...) 开头,它调用同一类的另一个构造函数。只有当调用的构造函数不是以 this(...) 或 super(...) 开头时,才会自动调用 super()。

    我想说的是,在构造了一个对象之后 super(...) 已经被调用(如果该类不是 java.lang.Object)。

    【讨论】:

      【解决方案3】:

      这里是使用this(...)的或多或少的实际示例

      public class Car {
      
          private final int numberOfDoors;
      
          public Car(int doors) {
              numberOfDoors = doors;
          }
      
          public Car() {
              this(4);    // default is 4 doors, calls the constructor above
          }
      }
      

      【讨论】:

        【解决方案4】:

        构造函数主体中的第一条语句应该是 this 或 super ,如果没有的话,默认编译器会保留一个 super() 关键字(没有参数)。 所以构造函数体是这样执行的:

        1. 会根据this或super关键字执行,那么

        2. 它将执行所有 IIB(作为自上而下的方法),然后

        3. 它将执行程序员保存的所有语句(如sop、initilization)

        Class A{
            A() {
                this(10);    //or super,....... execution statement 1
                // executing IIB's, execution statement 2
                System.out.println("from A()");   // execution statement 3
            }
        
            A(int i) {
                System.out.println("from A(int)");
            }        
            {
                System.out.println("from IIB-1");
            }
        
            public static void main(String[] args){
                A a = new A(); //calling constructor A()
                System.out.println("from main");
            }
            {
                System.out.println("from IIB-2");
            }
        }
        

        输出:

        from IIB-1
        from IIB-2
        from A(int)
        from A()
        from main
        

        【讨论】:

          【解决方案5】:

          在 Java 中,当您使用 new (如 C c = new C();)实例化任何对象时,它会委托其超类构造函数首先创建它。

          So in your case new C() --> Delegates to --> B() --> Delegates to A()
          So execution flow is as below:
          
          1) A() will Prints : 2
          2) B() will calls  B(1 )  prints  3 and control return to B() constructor
          3) B() will prints : 4
          4) C() will prints : 6
          
          I hope it is now clear
          

          【讨论】:

            猜你喜欢
            • 2016-04-02
            • 2020-03-20
            • 1970-01-01
            • 2017-12-24
            • 1970-01-01
            • 2016-02-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多