在Java中创建用户定义的类时,不要将其指定为扩展Object。但是这个类仍然是一个对象。这是如何运作的? javac或JVM如何将类的所有属性都注入用户定义的类?
答案 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无法确定您在源代码中执行或未指定的内容。