调用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();
}
ADDITION
根据我的问题,我的意思是限制可能类似于以下情况:
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)获取编译器错误“在显式调用构造函数时无法引用实例方法”
那么,为什么我们不能废除“第一线要求”而只依赖于最后一个错误呢?
答案 0 :(得分:3)
是的,作为构造函数中的第一个调用,需要调用super()
。
以至于如果你把它留下来,编译器会(尝试)为你插入这个电话。要了解原因,您需要了解Java设计者的理念。 Gosling一直在计算机科学家的阵营中,认为访问部分初始化的对象是计算机程序中较大的错误来源之一。因此,他设计了一个严格的初始化层次结构,有助于缓解这个问题。你是否同意哲学是没有实际意义的 - 但重要的是要认识到它在Java中的重要概念,例如引用vs指针,或实际的有界数组。应该注意的是,即使像Objective C这样的语言允许你随时调用初始化,也需要很长时间才能执行初始化链接,除非他们需要通过约定来实现,而不是严格的语言规则。
我不确定你在你的例子中试图说明什么 - 但是经过Java的多年开发我怀疑你会发现很多情况下你真的需要在调用super之前执行逻辑。
答案 1 :(得分:0)
构造函数调用与在调用该类的构造函数之前调用的层次结构中的每个类的超链接相关联。由于Java中的所有类都继承自对象类,因此首先为每个类调用Object类的构造函数,理由是对象的内存分配由Object类的构造函数完成