【问题标题】:Instance initialization block and subclasses实例初始化块和子类
【发布时间】:2013-04-14 05:33:15
【问题描述】:

我对实例初始化块应该何时运行感到困惑。 根据 Kathy Sierra 的书:

每次创建类实例时都会运行实例初始化块

所以,根据this question 和 java 的文档,考虑有两个类:父类和子类:

实例化子类对象只会创建子类的 1 个对象 类型,但调用其所有超类的构造函数。

根据上述: 为什么每次实例化子类的对象时都会调用位于超类中的实例初始化块?这不是实例化超类的新对象。

【问题讨论】:

    标签: java inheritance initialization initialization-block


    【解决方案1】:

    虽然这是一篇旧文章,但我发现了这个值得分享的概念

    既然我们在这里讨论的是实例块,那么实例代码流是如何在父子关系类中执行的 //子扩展父 如果我们为 Child 创建一个对象

    1)从父到子识别类的实例成员

    2) 仅在父类上执行实例变量赋值和实例块

    3)父构造函数的执行

    4) 仅在子类上执行实例变量赋值和实例块

    5)子构造函数的执行

    【讨论】:

      【解决方案2】:

      编译后实例初始化块成为构造函数的一部分。 javac 只是将init块添加到每个构造函数中,就是这样:

      public class Test1 {
          int x;
          int y;
      
          {
              x = 1;
          }
      
          Test1() {
              y = 1;
          }
      }
      

      相当于这个:

      public class Test1 {
          int x;
          int y;
      
          Test1() {
              x = 1;
              y = 1;
          }
      }
      

      所以初始化块在构造函数运行时运行。

      【讨论】:

      • 实际上,还有更多内容,实例初始化程序块在对超级构造函数的任何现有调用之后被添加到构造函数中。请参阅java-blog.kbsbng.com/2016/01/… 以供参考
      【解决方案3】:

      因为在子的构造函数中总是存在对父构造函数的隐式super() 调用(如果没有显式调用)。

      【讨论】:

        【解决方案4】:

        不是实例化超类的新对象。

        其实是这样的。

        子类的每个实例都隐含地包含其超类的一个实例。

        超类构造函数总是作为任何构造函数的第一步被调用(并且反过来运行超类的任何实例初始化程序块)

        【讨论】:

        • 我知道所有的超类构造函数都会被调用,但我的理解是不管调用这些构造函数:只有一个对象被实例化/创建在那里,那就是子类。跨度>
        • 你可以这样看。但是你也可以说同一个对象也是超类的一个实例。可以肯定的是,该实例除了包含它自己的之外,还包含超类定义的所有字段。
        猜你喜欢
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        • 2016-06-13
        • 2017-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多