【问题标题】:What does the default constructor in the class OBJECT do? [duplicate]OBJECT 类中的默认构造函数是做什么的? [复制]
【发布时间】:2017-11-26 19:59:00
【问题描述】:

我是一名Java初学者,学习Java编译器规则如下:

  1. 如果该类没有超类,则将其扩展为 Object 类
  2. 如果类没有构造函数,添加一个默认的无参数构造函数
  3. 如果构造函数的第一行不是“super()”或“this()”,添加“super()”调用超类的默认构造函数。

我知道我们创建的所有对象都是从超类 Object 派生的。 我的问题是 Object 类中的构造函数在调用时做了什么?

编辑:我的问题是构造函数在 Object 类中做了什么?我知道子类默认调用超类的构造函数。

例如,我有以下代码(我显式扩展到 Object 并调用 super() 来说明编译器的作用)。我的问题是,对 super() 的调用是做什么的?

public class Person extends Object
{
    private String name;
    public Person(String n)
        {   
            super();
            this.name = n;
        }
}

【问题讨论】:

  • 确实没有理由用 Java 写 extends Object
  • @M.Prokhorov 同意。上面的代码是讲师展示的,用来说明编译器是如何工作的。
  • 另外,If the class has no constructor, add a default no-parameter constructor 也是错误的经验法则。
  • 您可以参考this。希望这会对你有所帮助。
  • @M.Prokhorov 您能否详细说明为什么该规则是错误的?

标签: java inheritance constructor superclass


【解决方案1】:

所有没有任何显式超类的 Java 类都从 Object 扩展而来,Object 本身除外。无需在代码中明确说明,编译器会处理。

另外,构造函数中的super() 调用将调用Object 的构造函数。如果您查看实现,您会发现 Object 根本没有任何构造函数,因此它将使用一个不执行任何操作的隐式空构造函数。诸如构造一个 vtable 以确保可以使用继承的方法或初始化对象的监视器等细节不是构造函数的一部分,而是在调用 new 运算符时由 JVM 实现执行。

public Object() {

}

Object 类几乎没有在大多数类中派上用场的方法。例如,臭名昭著的toString() 是在 Object 类中实现的。此外,hashCode() 也在那里实现。

我建议您深入查看 Object.class 文件,以了解每个 Java 类中继承了哪些方法。

关于顶部的 3 条规则,对于学术目的来说“很好”,但在现实中从未使用过。您永远不会看到明确的extends Object,只有在需要覆盖默认行为时才调用super()this()

此外,避免滥用继承并使用更多组合(实现接口),但这取决于每个用例。

【讨论】:

  • '所有没有任何显式超类的 Java 类都扩展自 Object',Object 本身除外。
【解决方案2】:

我的问题是,对 super() 的调用是做什么的?

它调用java.lang.Object 的默认构造函数。并回答您似乎真正在问的问题,来自Java Language Specification, #8.8.9

8.8.9。默认构造函数

如果一个类不包含构造函数声明,则隐式声明一个默认构造函数。顶级类、成员类或本地类的默认构造函数形式如下:

默认构造函数具有与类相同的可访问性(第 6.6 节)。

默认构造函数没有形式参数,除非在非私有内部成员类中,默认构造函数隐式声明一个形式参数,表示该类的直接封闭实例(第 8.8.1 节、第 15.9.2 节、第15.9.3)。

默认构造函数没有 throws 子句。

如果声明的类是原始类Object,则默认构造函数的主体为空。否则,默认构造函数只会调用不带参数的超类构造函数。

注意最后一段。

【讨论】:

  • 那么就是说Object类中的构造函数什么都不做?
  • @misaikucing 没有“这意味着”。它明确表示java.lang.Object 的默认构造函数有一个空主体,您可以通过javap -c java.lang.Object 自己查看。
  • 解释得很好,明白了!
【解决方案3】:

例如,我有以下代码(我明确扩展到 对象并调用 super())。我的问题是,这个电话有什么作用 super() 做什么?

实际上,Object() 什么都不做。
现在,您不应该减少为任何子类构造函数调用 super()(带有或不带有 args)的约束,以防止您有一个没有显式扩展类的类。

这种情况是唯一一种调用super() 可能看起来没有用的情况。
但是一旦一个类扩展了一个不同于Object 的类,这个约束就非常有意义,因为子构造必须首先应用它的父构造。

但是语言以一般的方式指定了这一点。直接扩展 Object 的类也不例外。
可能是因为,它使事情变得更简单,而这并不是真正的约束,因为编译器会为您添加对超级默认构造函数的调用:super()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多