繁体   English   中英

在java中调用超类构造函数规则

[英]calling super class constructor rules in java

OCP考试准备中有一个问题,如下:

Which of the following pairs, when inserted into the blanks, allow the code to compile



  1:  public class Howler {
  2:     public Howler(long shadow) {
  3:        ________________;
  4:     }
  5:     private Howler(int moon) {
  6:        super();
  7:     }
  8:  }
  9:  class Wolf extends Howler {
  10:    protected Wolf(String stars) {
  11:       super(2L);
  12:    }
  13:    public Wolf() {
  14:       _______________;
  15:    }
  16: }

答案是:

 1- this(3) at line 3, this("") at line 14
and 
2- this((short)1) at line 3, this(null) at line 14

现在我很困惑,因为有一条规则是子类应该始终为父类调用构造函数,而父类没有无参数构造函数,那么这些答案是如何专门针对第 14 行正确的?

因为有一个规则,子类应该总是调用父类的构造函数

那条规则是错误的。 或者至少,过于简单化的结果大多是错误的。

你用java编写的每个构造函数都将无法编译,除非它做的第一件事是调用另一个构造函数。 您可以选择: 使用super(params);调用父级的构造函数之一super(params); ,或者,使用this(params);调用您自己的构造函数之一this(params); .

此规则甚至适用于您“免费”获得的默认构造函数,它看起来像public YourType() {}

但是,如果super(); 将是有效的(例如,在您的父类中有一个可访问的无参数构造函数),并且您失败了规则(您的构造函数既不以this()也不以super()开头,那么 java 将假设您打算以开头super();并把它放在你身上。

换句话说,编译器这样做:

  1. 取所有不以super(...this(...开头的构造函数,并将super();添加到顶部。
  2. 如果构造函数为零,则添加public ThisType() {super();}
  3. 现在编译它; 如果任何构造函数不以super(..this(..开头,那就是编译器错误。

因为所有构造函数都是这样工作的,所以你不能“侥幸逃脱”——你可以随心所欲地调用this() ,但最终你必须得到一个调用super的构造函数,否则它就是一个无限循环。

因此,最终,所有构造函数最终都会调用父构造函数之一。 java.lang.Object是唯一的例外。Javac 不可能编译它,代表 jlObject 的类文件与字节码一起被黑客攻击;在字节码级别,此规则不存在jlObject的一个构造函数确实什么都不做。甚至没有super();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM