Java Object 类

Object类

Java Object 类

java.lang.Object 是 Java 语言类层次结构的根类,也是整个 Java 类继承体系的唯一顶层超类(ultimate superclass)。Java "万物皆对象" 的核心设计原则通过 Object 类落地,所有 Java 对象(包括自定义类实例、系统类实例、数组对象等)均归属于 Object 类型体系,Object 类定义了所有 Java 对象的基础行为契约,是 Java 面向对象(OOP)体系的底层基石。

Object 类隶属于 java.lang 包(Java 核心类库的基础包),该包由 Java 运行时环境(JRE)自动导入,因此使用 Object 类时无需通过 import 语句显式导入,可直接使用。

继承规则:

对于所有类类型,若未通过 extends 关键字显式声明父类,则编译器会自动为其插入 extends Object 的隐式声明;若已显式声明父类则通过 父类链间接继承 Object;因此所有类都直接或间接继承 Object 类,遵循 Java 单继承的核心规则。

数组的特殊规则:

数组是 JVM 直接定义的特殊引用类型(无对应的.class文件,不由class关键字定义),但数组对象仍属于 Object 类型的实例:

一维 / 多维数组均可调用 Object 类的所有非 final 方法(如 toString()、equals()、hashCode());

数组类型未重写 Object 类的任何方法(如 equals() 仍默认比较引用地址,需通过 java.util.Arrays.equals() 实现内容比较);

可将数组对象赋值给 Object 类型变量(如Object arr = new int[10]),符合 "万物皆对象" 的设计逻辑。

Object 类的核心方法

Object 类的构造方法

Object 类仅定义一个 public 权限的无参构造器,且无其他重载构造形式

根据 Java 构造器的调用规则:

任何子类的构造器若未通过 super(...) 显式调用父类构造器,则编译器会自动在子类构造器的第一行插入 super() 语句,即隐式调用 Object 类的无参构造器,这是所有 Java 对象实例化时的底层基础,确保对象从顶层超类开始完成初始化。

Object 类的核心方法如下:

toString()

toString() 在 Object 中的源码如下:

getClass().getName():获得调用 toString() 方法的类的类名

Integer.toHexString(hashCode()):获得这个对象的哈希值的十六进制表示

输出格式:全限定类名@哈希码的十六进制表示

在JDK1.6的官方文档中解释为:

java 复制代码
public class Dog {

    String name;
    
    Integer age;
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "小花";
        dog.age = 2;
        System.out.println(dog);
        System.out.println(dog.toString());
    }
}

System.out.println(dog) 和 System.out.println(dog.toString()) 的输出结果完全一致,因为 Java 规定,当直接打印一个对象时,程序会自动调用这个对象的 toString() 方法,最终打印的是 toString() 返回的字符串

toString() 的重写

java 复制代码
public class Dog {

    String name;
    Integer age;

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "小花";
        dog.age = 2;
        System.out.println(dog);
        System.out.println(dog.toString());
    }
}

Dog 类重写了 toString(),输出结果是自定义的字符串

equals(Object obj)

源码如下:

基本数据类型无 equals () 方法,== 是其唯一比较方式,比较的是值的相等性;

引用数据类型的 == 始终比较引用的内存地址,判断是否指向同一个对象实例;

java.lang.Object 类的 equals (Object obj) 方法,默认实现为 return (this == obj),即与引用类型的 == 行为一致;子类可重写该方法,重新定义逻辑相等性规则,此时 equals () 与 == 无直接关联。

equals() 的重写

java 复制代码
class Student{

    int sNo;
    String name;
    int age;

    public void learn(){
        System.out.println(name+"在学习");
    }

    /**
     * toString重写
     * @return
     */
    public String toString(){
        return "学号:"+sNo+" 名字:"+name+" 年龄:"+age;
    }

    /**
     * equals重写
     * @param obj
     * @return
     */
    public boolean equals(Object obj) {
        boolean flag = false;
        if(obj instanceof Student){
            Student s = (Student)obj;
            if(this.sNo == s.sNo && this.age == s.age && this.name != null && s.name != null && this.name.equals(s.name)){
                flag = true;
            }
        }
        return flag;
    }
}

重写的 equals() 的核心逻辑:

先通过 instanceof 判断传入的 obj 是否是 Student 类型,避免类型转换异常,强转后比较 sNo 数值、age 数值、name(先判空再调用 java.lang.String 类重写后的 equals() 方法),若这三个属性都相等才返回 true,否则返回 false。

java 复制代码
public class ObjectTest {
    public static void main(String[] args){

        Student s = new Student();
        s.sNo = 1;
        s.name = "小明";
        s.age = 10;
        System.out.println(s);

        Student s1 = new Student();
        s1.sNo = 1;
        s1.name = "小明";
        s1.age = 10;
        System.out.println(s1);

        System.out.println(s == s1);

        boolean e = s.equals(s1);
        System.out.println(e);
    }
}

s == s1 的输出结果为 false,因为 == 比较引用变量指向的内存地址是否相同,s 和 s1 是两个不同的 Student 对象实例,在堆内存中的地址不同;
s.equals(s1) 的输出结果为 true,因为 Student 类重写了 equals() 方法,改为基于业务属性(学号、姓名、年龄) 判断相等性,而非地址。

hashCode()

由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数,每一个对象都有一个唯一的 hash 值。

hashCode () 的唯一核心用途是提升哈希集合的性能:

若无 hashCode(),HashMap 需遍历所有键用 equals () 比较,时间复杂度为 O(n);

有 hashCode(),HashMap 先通过 key.hashCode() 定位到对应的桶(时间复杂度为 O(1)),再在桶内通过 equals() 逐个比较键是否相等,性能得到大幅提升。

这里关键解读为什么 equals 相等则 hashCode 必须相等?

两个逻辑相等的对象,必须出现在同一个桶里,而出现在同一个桶的必要条件就是 hashCode 相同。

java 复制代码
class Student{

    int sNo;
    String name;
    int age;

    public void learn(){
        System.out.println(name+"在学习");
    }
}
java 复制代码
public class ObjectTest {
    public static void main(String[] args) {
    
        Student s = new Student();
        //获得这个对象的hash值
        int hv = s.hashCode();
        System.out.println("十进制:" + hv);
        //获得hash值的16进制
        String hvh = Integer.toHexString(hv);
        System.out.println("十六进制:" + hvh);

        System.out.println("-------------------------------");

        s = new Student();
        hv = s.hashCode();
        System.out.println("十进制:" + hv);
        hvh = Integer.toHexString(hv);
        System.out.println("十六进制:" + hvh);
    }
}

每一个对象都有一个唯一的 hash 值

getClass()

返回此对象运行时类的 Class 对象

java 复制代码
public class ObjectTest {
    public static void main(String[] args) throws Exception{
        Student s = new Student();
        Class c = s.getClass();
        System.out.println(c.getName());
    }
}

finalize()

相关推荐
悟能不能悟3 小时前
如何处理 丢失更新(不可重复读)
java
Wang's Blog3 小时前
Lua: 协程编程详解之从基础到多任务处理与应用实战
开发语言·lua
笙枫3 小时前
LangGraph Agent 架构基础:从概念到第一个可运行的Agent
开发语言·架构·php
李拾叁的摸鱼日常3 小时前
Java Optional 最佳实践+注意事项+避坑指南
java·后端·面试
雨中飘荡的记忆3 小时前
MyBatis配置解析模块详解
java·mybatis
qq_12498707533 小时前
基于微信小程序的科技助农系统的设计与实现(源码+论文+部署+安装)
java·大数据·spring boot·后端·科技·微信小程序·毕业设计
狂奔小菜鸡4 小时前
Day35 | Java多线程入门
java·后端·java ee
『六哥』4 小时前
IntelliJ IDEA 安装教程
java·ide·intellij-idea·intellij idea
艾迪的技术之路4 小时前
【实践】2025年线上问题解决与总结-1
java