Java中所有类默认继承Object是编译器与JVM共同保障的底层机制:编译期自动补extends Object,运行时通过getSuperclass()链式指向Object.class,所有实例天然拥有其8个公共方法。

Java中所有类都默认继承自Object,这不是语法糖,而是编译器和JVM共同保障的底层机制。理解它,关键不在“记住”,而在看清三件事:编译期怎么补、运行时怎么认、方法怎么用。
编译器自动补上extends Object
你写class Person { },Java编译器(javac)在生成字节码前,会悄悄把它等价为class Person extends Object { }。这个过程不报错、不提示,也不需要你写出来——只要没显式继承其他类,就一定隐式继承Object。
注意两点:
- 如果写了
class Person extends Animal { },那Person的父类就是Animal,不是Object;但只要Animal本身也继承自Object(几乎必然),那Person就间接继承了Object - 接口(
interface)不继承Object,但实现接口的类仍继承Object
JVM靠java.lang.Object类型确认根类身份
运行时,每个类的Class对象都有一个getSuperclass()方法。对任意非Object类调用它,最终都会链式返回Object.class。这是因为JVM加载类时,会严格校验继承链终点必须是java.lang.Object——这是JVM规范强制要求的。
立即学习“Java免费学习笔记(深入)”;
你可以验证:
System.out.println(new String().getClass().getSuperclass()); // 输出 class java.lang.ObjectSystem.out.println(Object.class.getSuperclass()); // 输出 null(Object没有父类)
所有实例天然拥有Object的8个公共方法
因为继承关系成立,每个对象都能直接调用Object定义的方法,比如toString()、equals()、hashCode()、clone()(需实现Cloneable)、wait()/notify()等。这些不是“内置功能”,而是继承得来的成员。
常见误区:
-
toString()打印出ClassName@hashcode,是因为你没重写它——父类Object的默认实现就这么干 -
equals()默认比较引用(==),所以两个内容相同但不同对象的字符串,用默认equals会返回false -
getClass()和finalize()(已弃用)也是Object提供的,子类不可重写getClass()
泛型和集合依赖Object机制才能统一处理
早期Java(1.4之前)没有泛型,ArrayList内部用Object[]存数据,靠向上转型把任意对象塞进去;取出来时再强制转回原类型。这种“擦除+转型”的设计,根基就是所有类都是Object子类。
即使现在有了泛型,编译后依然会擦除为Object(桥接方法、类型检查都基于此)。比如ArrayList<String>在字节码里仍是操作Object数组。
这也解释了为什么不能写ArrayList<int>——int是基本类型,不是Object子类;必须用Integer(它是Object子类)。


















