当前位置: 首页 > 知识库问答 >
问题:

在Java中调用对象类的构造函数的目的是什么?

臧烨烁
2023-03-14

上这个简单的课...

public class Gen
{
    public static void main (String[] Args)
    {
        Gen genny = new Gen();
    }
}

JLS的第8.8.9节指出,“如果一个类不包含构造函数声明,那么默认构造函数将被隐式声明。”它还说,只要我们不在java.lang.object类中,那么“默认构造函数只是调用没有参数的超类构造函数。”

因此,因为类Gen扩展了java.lang.object,我们被迫通过Super()调用java.lang.object的构造函数,作为隐式创建的默认构造函数的一部分。

同样地...

public class Gen extends Object
{   
    public static void main (String[] Args)
    {
        Gen genny = new Gen();
    }
    
    public Gen()
    {
        
    }
}

即使我们显式地为Gen声明构造函数,JLS的第8.8.7节规定“如果构造函数体不是以显式构造函数调用开始,并且被声明的构造函数不是原始类对象的一部分,那么构造函数体隐式地以超类构造函数调用“super()开始;“,对其直接超类的构造函数的调用,不接受任何参数。”

因此,Java再一次超越了我们,让我们调用Java。通过super()实现lang.object的构造函数。但是java。lang.object的构造函数实际上有一个空体。它什么都没做。构造函数的实际用途只有1)如果您编写它以初始化类的实例变量,或2)如果它直接/间接调用其超类的构造函数以初始化其实例变量<代码>java。lang.object的构造函数不做这两件事,因为它1)没有实例变量,2)是继承层次结构的根。所以它是一个无意义的构造函数。现在,在我们的类Gen中,我们被无意义地强制调用一个无意义的构造函数。

为什么这样做?为什么Java人不能说“好的,如果类是Java.lang.object的直接子类,那么我们不会隐式定义构造函数,如果构造函数显式存在,我们也不会隐式调用super()。”老实说,为什么还要为java编写构造函数呢。lang.object首先是空的吗?

共有1个答案

傅正阳
2023-03-14

首先,没有必要这样写:

 public class Gen extends Object {

如果一个类没有显式地将其他类作为其直接超类,那么它会隐式地扩展Object。没有必要告诉编译器。

Yes在所有类中(除了Object)都必须调用其超类的构造函数。即使超类是Object。但没关系。正如规范所说,如果要调用的构造函数是无参数构造函数,那么您不需要显式的Super调用。编译器为您注入Super调用。

对在我遇到的所有Java实现中,对象的构造函数都是空的。但我不认为JLS要求这样做。无论哪种方式,JLS都声明将调用构造函数。

然而这并不是说编译器无法优化对对象()的调用。这就是他们所做的。(我记不起JVM规范是否要求字节码编译器发出对字节码中的对象()的调用。但即使是这样,JIT编译器也可以摆脱它。)

他们为什么用这些术语来具体说明?

>

  • 主要是因为如果Java语法和语义学中的特例较少,规范更容易理解,语言也更容易使用。

    “如果超类是Object,则您不能拥有Super()类”将是一种特殊情况。使语言工作不需要复杂性,如果您强迫程序员在这种情况下省略Super()调用,它肯定对程序员没有帮助。

    此外,如果有充分的理由这样做的话,当前的方法允许Java实现具有非空的构造函数。(但我怀疑他们在设计Java时是否认真考虑过这一点。)

    无论哪种方式,这都是Java 1.0之前的方式,他们现在不会改变。目前的方法实际上不会引起任何问题,也不会增加任何可观的开销。

  •  类似资料:
    • 问题内容: 考虑以下代码: 如果我们在超类中有一个构造函数,那么我们为子类构造的每个对象(例如,用于类调用的对象及其父对象)都将调用它。 为什么会这样? 该程序的输出为: 在超类的构造函数中 在子类的构造函数中 总和是25 在超类的构造函数中 在子类的构造函数中 总和是29 问题答案: 因为它将确保在调用构造函数时,它可以依赖于其超类中已初始化的所有字段。 请参阅此处的 3.4.4

    • 问题内容: 在Java规范(http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9)中,new具有以下形式: 新版本之后的第一个可选类型参数列表的目的是什么?通过阅读第15.9节,我找不到它(对类型实参列表的所有引用似乎都在类型/标识符之后引用该列表)。在标准Java编译器上测试随机位会产生令人困惑的结果: 在这些

    • 问题内容: 由于我们无法实例化抽象类,那么在抽象类中具有构造函数的必要性是什么? 问题答案: 抽象类被设计为可扩展的,子类中的每个构造函数都必须执行对基类的构造函数的调用,因此,您的抽象类中需要构造函数。 抽象类是一个骨架,因此直接实例化它是没有意义的,因为它仍然不完整(孩子们会提供其余的东西)。

    • 问题内容: 这些来自github上的spring amqp示例,位于https://github.com/SpringSource/spring-amqp- samples.git 这些是 什么类型的Java构造函数?它们是吸气剂和吸气剂的捷径吗? 与此相反 问题答案: 这些构造函数被重载以使用调用另一个构造函数。第一个无参数构造函数使用空参数调用第二个。第二呼叫的第三构造(未示出),其必须采取,

    • 问题内容: 为什么Java 中的类有一个? 我们无法实例化一个类,它的构造是什么? 有什么想法吗? 问题答案: Java中的构造函数实际上并不“构建”对象,而是用于初始化字段。 想象一下,您的抽象类具有字段x和y,并且无论最终创建什么实际的具体子类,您总是希望以某种方式对其进行初始化。因此,您将创建一个构造函数并初始化这些字段。 现在,如果您的抽象类有两个不同的子类,则在实例化它们时,将调用它们的