类不扩展java.lang.Object

时间:2009-08-28 04:39:12

标签: java inheritance compiler-construction

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

5 个答案:

答案 0 :(得分:12)

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

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

public class test {}

并编译它,然后运行

javap -c test

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

Compiled from "test.java"
public class test extends java.lang.Object{
public test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

}

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

答案 1 :(得分:4)

所有java类都隐式扩展java.lang.Object。来自documentation

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

以下是JVM spec的链接:

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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