类不扩展java.lang.Object

在Java中创建用户定义的类时,不要将其指定为扩展Object。 但是这个类仍然是一个对象。 这是如何运作的? javac或JVM如何将类的所有属性注入用户定义的类?

如果您实际上没有编写extends Object ,编译器会为您插入它。

编辑 :显然我对是否实际插入代码造成了一些混淆。 我不完全确定自己,所以我做了一个小实验:在文件test.java创建以下类:

 public class test {} 

并编译它,然后运行

 javap -c test 

反汇编字节码。 看看会发生什么:

 编译自“test.java”
 public class test extends java.lang.Object {
 public test();
  码:
    0:aload_0
    1:invokespecial#1;  //方法java / lang / Object。“”:()V
    4:回归

 } 

所以,是的,编译器确实extends java.lang.Object (或等效的字节码)插入到类中。

所有java类都隐式扩展java.lang.Object。 从文档 :

Class Object是类层次结构的根。 每个类都有Object作为超类。 所有对象(包括数组)都实现此类的方法。

这里还有一个指向JVM规范的链接:

标准类Object是所有其他类的超类(第2.8.3节)。 Object类型的变量可以保存对任何对象的引用,无论它是类的实例还是数组。 所有类和数组类型都inheritanceObject类的方法。

好吧,这可能是一个滑稽的答案(我最喜欢的那种),但如果你指定一个父类,它可能就像它派生一个类一样。 如果您正在编写编译器,那不就是这样做的吗?

这是因为所有用户定义的类型都隐式地从Objectinheritance。

要说JVM“注入”属性或方法到类中使得它听起来像编译器或运行时事后的事情,就像.class文件不同一样。 实际上,所有发生的事情是,当解析器发现你没有包含任何带有extends基类时,它只是假装你明确指定了Object 。 从那时起,编译器将其视为与您自己键入的相同,并且JVM无法确定您在源代码中执行或未指定的内容。