0

调用super()构造函数应该是构造函数的第一行吗?如果是,那为什么?为什么在构造函数调用之前不能做一些简单的有限计算,比如构造函数参数计算?

我发现内部类构造函数的情况可以用闭包规范调用:

class A {
    class Inner1 {
        Inner1() {
            // do something
        }
    }
}

class B {
    A a1 = new A();
    A a2 = new A();

    class Inner2 extends A.Inner1 {
         Inner2(boolean sel) {
             (sel?a1:a2).super();
         }
    }

}

这个案例表明我们可以为基类构造函数选择封闭实例。为什么选择逻辑应该如此有限?为什么一个人不能写这样的东西

if( sel ) {  
    a1.super();
}
else {
    a2.super();
}

添加

通过我的问题,我的意思是限制可能类似于以下情况:

public class Base {

private final String content;

public Base(String content) {
    this.content = content;
}

public String getContent() {
    return content;
}

}


public class Derived extends Base {

public Derived(String content) {
    super(String.format("Current value of content is %s.", getContent()));
}


}

在后一种情况下,我:

1) 满足super()排在第一线的要求

2)违反施工顺序

3) 获得编译器错误“在显式调用构造函数时无法引用实例方法”

那么,为什么我们不能取消“第一线要求”而只依赖最后一个错误呢?

4

2 回答 2

3

是的,super()作为构造函数中的第一个调用需要调用。

如此之多,以至于如果您将其排除在外,编译器将(尝试)为您插入调用。要了解其中的原因,您需要了解 Java 设计者的哲学。Gosling 一直属于计算机科学家的阵营,他们认为访问部分初始化的对象是计算机程序中更大的错误来源之一。因此,他设计了一个严格的初始化层次结构来帮助缓解这个问题。你是否同意这个哲学是没有意义的——但重要的是要意识到它在 Java 中的一个重要概念,例如,引用与指针,或真实的有界数组。应该注意的是,即使像 Objective C 这样允许您随时调用初始化的语言,也会竭尽全力强制执行初始化链接,除了他们需要通过约定来这样做,而不是严格的语言规则。

我不确定您在示例中试图说明什么 - 但经过多年的 Java 开发后,我怀疑您会发现很多情况下您确实需要在调用 super 之前执行逻辑。

于 2012-05-23T21:52:08.050 回答
0

在调用该类的构造函数之前,构造函数调用与层次结构中每个类的 super 链接。由于Java中的所有类都继承自对象类,因此每个类都会首先调用Object类的构造函数,原因是对象的内存分配是由Object类的构造函数完成的

于 2012-05-23T20:53:32.193 回答