Java 调用super()构造函数应该是构造函数的第一行吗?
调用Java 调用super()构造函数应该是构造函数的第一行吗?,java,constructor,closures,inner-classes,superclass,Java,Constructor,Closures,Inner Classes,Superclass,调用super()构造函数应该是构造函数的第一行吗?若然,原因为何?为什么我不能在调用构造函数之前进行一些简单的有限计算,例如,构造函数参数计算 我发现了一种内部类构造函数的情况,它可以通过闭包规范调用: class A { class Inner1 { Inner1() { // do something } } } class B { A a1 = new A(); A a2 = new A();
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) 获取编译器错误“显式调用构造函数时无法引用实例方法”
那么,为什么我们不能取消“第一行要求”而只依赖于最后一个错误呢?在调用该类的构造函数之前,构造函数调用被链接到层次结构中被调用的每个类的super。由于Java中的所有类都继承自对象类,所以每个类都首先调用对象类的构造函数,原因是对象类的构造函数完成对象的内存分配在调用该类的构造函数之前,构造函数调用被链接到层次结构中每个类的super。由于Java中的所有类都继承自对象类,因此每个类都首先调用对象类的构造函数,原因是对象类的构造函数完成了对象的内存分配是的,构造函数中的第一个调用需要调用
super()
如此之多,以至于如果您忽略它,编译器将(尝试)为您插入调用。要理解原因,您需要了解Java设计者的理念。高斯林一直是计算机科学家的阵营,他们认为访问部分初始化的对象是计算机程序中更大的错误来源之一。因此,他设计了一个严格的初始化层次结构,这将有助于缓解这个问题。您是否同意这一理念还没有定论,但重要的是要认识到,在Java中,这一概念与引用、指针或真实的有界数组一样重要。应该注意的是,即使像Objective C这样允许您随时调用初始化的语言,也会花费大量时间来强制执行初始化链接,只是它们需要通过约定来执行,而不是严格的语言规则
我不确定您在示例中试图说明的是什么-但经过多年的Java开发,我怀疑您会发现许多情况下在调用super之前确实需要执行逻辑。是的,在构造函数中第一次调用时需要调用super()
如此之多,以至于如果您忽略它,编译器将(尝试)为您插入调用。要理解原因,您需要了解Java设计者的理念。高斯林一直是计算机科学家的阵营,他们认为访问部分初始化的对象是计算机程序中更大的错误来源之一。因此,他设计了一个严格的初始化层次结构,这将有助于缓解这个问题。您是否同意这一理念还没有定论,但重要的是要认识到,在Java中,这一概念与引用、指针或真实的有界数组一样重要。应该注意的是,即使像Objective C这样允许您随时调用初始化的语言,也会花费大量时间来强制执行初始化链接,只是它们需要通过约定来执行,而不是严格的语言规则
我不确定您在示例中试图说明的是什么-但经过多年的Java开发,我怀疑您会发现许多情况下在调用super之前确实需要执行逻辑。
super()
如果您使用它,则必须将其作为构造函数调用的第一行-但是请检查以下线程:或者:谢谢!变通方法很有趣,但它也很有趣,为什么Java如此,也就是说,如果我在调用super之前做了一些事情,那又有什么不好呢?例如,如果您在调用super()
之前做了一些事情,我可能不得不在调用super之前不访问实例成员。@SuzanCioc。Java将停止您的程序并告诉您修复它。@Suzan Cioc,Birrreee提供的第二个链接涵盖了这一点question@Suzan有些语言(python)允许稍后调用或根本不调用超类的构造函数。这显然会产生不良后果,但我们都知道,首先调用super()
并不能解决所有问题,还会产生大量新问题。不过这是一种简化,因为这意味着我们不必将对象分配和初始化分为两个单独的部分。我假设它避免了一种经常出现的问题。super()
必须作为构造函数调用的第一行,如果你使用它的话-但是检查这个线程:或者这个:谢谢!变通方法很有趣,但它也很有趣,为什么Java如此,也就是说,如果我在调用super之前做了一些事情,那又有什么不好呢?例如,如果您在调用super()
之前做了一些事情,我可能不得不在调用super之前不访问实例成员。@SuzanCioc。Java将停止您的程序并告诉您修复它。@Suzan Cioc,Birrreee提供的第二个链接涵盖了这一点question@Suzan有些语言(python)允许稍后调用或根本不调用超类的构造函数。这显然会产生不良后果,但我们都知道,首先调用super()
并不能解决所有问题,还会产生大量新问题