【问题标题】:In constructor, why can fields of current class not referred to before the superclass constructor is executed? [duplicate]在构造函数中,为什么在执行超类构造函数之前不能引用当前类的字段? [复制]
【发布时间】:2017-07-08 14:26:59
【问题描述】:

例如,

Subclass extends ParentClass {
  private String subclassField;
  Subclass() {
    // it's illegal
    super(subclassField);
  }
}

这会引入编译错误“在调用构造函数时无法引用实例字段”。

对于 StackOverflow 中有关此场景的类似问题的一些答案,请转到“因为当前实例仍在构建中”或“尚未在堆中创建的实例”。

然而,令人困惑的是, 在超类构造函数中,可以调用可覆盖的成员方法,这些方法可以访问子类当前实例的字段。在 Java 中也可以。

我的查询是

  1. 在实例构造过程中,从什么时候开始可以引用子类的字段?

  2. “在调用构造函数时不能引用实例字段”,而在超类构造函数中调用可覆盖的方法是可以的,背后的基本原理是什么?

【问题讨论】:

  • 您对#2 提出的实际 问题是什么?例如,为什么基本原理很重要?语言就是这样。
  • 在 Java 中没关系:编译器接受它,但这是不好的做法。无论如何,所有字段都将具有其默认值,因此您可以只传递 null 而不是 subclassField。传递子类字段有 99.999% 的机会成为错误,因此禁用它是有意义的。调用可覆盖的方法可以很好,因为它不一定访问子类字段。

标签: java class oop inheritance


【解决方案1】:

在实例构造过程中,从什么时候开始可以引用子类的字段?

从对超类构造函数的调用完成的那一刻开始。请记住,在此之前,实例字段无论如何都只会有它们的默认值——即使您在它们上使用了初始化程序或实例初始化块;在这两种情况下,执行此操作的代码都插入到类的构造函数中,超类构造函数调用之后。考虑这对类:

class ParentClass {
    ParentClass(String s) {
    }
}

class Subclass extends ParentClass {
    private String subclassField = "init";

    Subclass() {
        super("bar");
    }
}

如果我们通过javap -c Subclass查看Subclass的字节码,我们会看到:

类子类扩展父类{ 子类(); 代码: 0:aload_0 1: ldc #1 // 字符串条 3: invokespecial #2 // 方法 ParentClass."":(Ljava/lang/String;)V 6:aload_0 7: ldc #3 // 字符串初始化 9: putfield #4 // 字段 subclassField:Ljava/lang/String; 12:返回 }

请注意,它编译我们的代码就好像我们是这样编写的:

class Subclass extends ParentClass {
    private String subclassField;

    Subclass() {
        super("bar");
        this.subclassField = "init"; // *** Note this moved
    }
}

(是的,如果您好奇的话,如果有多个构造函数,该代码会在每个构造函数中重复。)

“在调用构造函数时不能引用实例字段”背后的基本原理是什么,而在超类构造函数中调用可覆盖的方法是可以的?

你得问问詹姆斯·高斯林。但是考虑到与实例字段不同,实例方法在超类构造函数调用之前具有有用的值,实际上在构造期间使用方法有时会非常有用。然而,使用 可覆盖 方法是不好的做法;您在构造过程中使用的任何方法(直接或间接)都应该是最终的或私有的(例如,有效的最终方法)。编译器不会为您做出区分。如果现在正在编写规则,也许会。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多