【Java 学习】Java的生命之源:走进Object类的神秘花园,解密Object类的背后故事

💬 欢迎讨论:如对文章内容有疑问或见解,欢迎在评论区留言,我需要您的帮助!

👍 点赞、收藏与分享:如果这篇文章对您有所帮助,请不吝点赞、收藏或分享,谢谢您的支持!

🚀 传播技术之美:期待您将这篇文章推荐给更多对需要学习Java语言、低代码开发感兴趣的朋友,让我们共同学习、成长!

1. Object 类

1.1 为什么所有类都继承 Object 类?

在Java中,Object 类是所有类的根类。也就是说,所有的类(包括用户自定义的类)都直接或间接继承自 Object 类。这是因为在 Java 中,Object 是所有类层次结构的最顶端类。

为什么所有类都继承 Object 类?

  1. 统一的根基 :Java 为了实现统一性,决定所有类都直接或间接继承自 Object 类。这意味着每个类都可以拥有 Object 类的一些通用方法,这样使得不同类型的对象可以被处理得更加一致。

  2. 常用方法 :Object 类提供了一些常用方法,这些方法被所有类继承。比如:

    • toString():返回对象的字符串表示。
    • equals(Object obj):判断两个对象是否相等。
    • hashCode():返回对象的哈希码。
    • clone():创建并返回当前对象的副本。
    • getClass():返回对象的类信息。
    • notify(), notifyAll(), wait():用于多线程编程。

这些方法大多数类都会使用,或者根据需要进行重写,以便提供不同的行为。

  1. 多态性和泛型 :Java 中的多态性和泛型常常依赖于 Object 类。例如,在方法中接受一个 Object 类型的参数,就可以传入任何类型的对象。而且通过 Object 类的方法,可以对不同类型的对象进行统一的操作。

1.2 统一操作–举例

  1. toString() 方法
    toString() 方法是 Object 类提供的一个方法,默认返回对象的类名加上对象的哈希码的字符串表示。但是你可以在自己的类中重写这个方法,使其返回更具意义的信息。

    ```java
    class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
    

    }

    class Car {
    String brand;
    String model;

    Car(String brand, String model) {
        this.brand = brand;
        this.model = model;
    }
    
    @Override
    public String toString() {
        return "Car{brand='" + brand + "', model='" + model + "'}";
    }
    

    }

    public class Main {
    public static void main(String[] args) {
    Person person = new Person("John", 30);
    Car car = new Car("Toyota", "Camry");

        // 使用toString()输出对象的字符串表示
        System.out.println(person.toString()); // Person{name='John', age=30}
        System.out.println(car.toString());    // Car{brand='Toyota', model='Camry'}
    }
    

    }

    ```

  2. equals() 方法
    equals() 方法用于判断两个对象是否“相等”,默认的实现是比较对象的内存地址,但你可以重写它来根据类的字段比较对象的内容。

    ```java
    class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true; // 判断是否是同一对象
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }
    

    }

    public class Main {
    public static void main(String[] args) {
    Person person1 = new Person("John", 30);
    Person person2 = new Person("John", 30);
    Person person3 = new Person("Alice", 25);

        // 使用equals()比较对象是否相等
        System.out.println(person1.equals(person2)); // true
        System.out.println(person1.equals(person3)); // false
    }
    

    }

    ```

  3. hashCode() 方法
    hashCode() 方法用于返回对象的哈希值,通常与 equals() 配合使用。如果两个对象相等,那么它们的 hashCode() 也应该相等。

    ```java
    class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }
    
    @Override
    public int hashCode() {
        return 31 * name.hashCode() + age;
    }
    

    }

    public class Main {
    public static void main(String[] args) {
    Person person1 = new Person("John", 30);
    Person person2 = new Person("John", 30);

        // 使用hashCode()获取对象的哈希值
        System.out.println(person1.hashCode()); // 打印哈希值
        System.out.println(person2.hashCode()); // 打印哈希值
        System.out.println(person1.equals(person2)); // true
    }
    

    }

    ```

1.3 Object 类中的所有方法

下图就是Object类,在包java.lang
在这里插入图片描述
如果把Object类中的注释全部删去,Object类的代码如下:

```java
/*
 * Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang;

import jdk.internal.misc.Blocker;
import jdk.internal.vm.annotation.IntrinsicCandidate;

public class Object {

    @IntrinsicCandidate
    public Object() {}

    @IntrinsicCandidate
    public final native Class getClass();


    @IntrinsicCandidate
    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }

    @IntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    @IntrinsicCandidate
    public final native void notify();

    @IntrinsicCandidate
    public final native void notifyAll();


    public final void wait() throws InterruptedException {
        wait(0L);
    }

    public final void wait(long timeoutMillis) throws InterruptedException {
        long comp = Blocker.begin();
        try {
            wait0(timeoutMillis);
        } catch (InterruptedException e) {
            Thread thread = Thread.currentThread();
            if (thread.isVirtual())
                thread.getAndClearInterrupt();
            throw e;
        } finally {
            Blocker.end(comp);
        }
    }

    // final modifier so method not in vtable
    private final native void wait0(long timeoutMillis) throws InterruptedException;

    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                    "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }

    @Deprecated(since="9", forRemoval=true)
    protected void finalize() throws Throwable { }
}

```

我们可以从Object类中看到我们常用的toString方法、clone方法。

2. Object 类中的 clone() 方法

2.1 clone方法的定义和用途

Object 类中的 clone() 方 法用于创建当前对象的一个副本(即对象的浅拷贝)。它是一个受保护的方法(用protected修饰),所以默认情况下只有 Object 类本身及其子类可以调用。在实际开发中,clone() 方法常常被重写,以便提供更灵活的复制功能。

clone方法的声明如下:

```java
protected Object clone() throws CloneNotSupportedException;


```

说明

  • 返回值类型:Object 类型。返回的是当前对象的副本,因此返回值需要被强制转换为具体的类型。
  • 异常:CloneNotSupportedException,如果对象的类没有实现 Cloneable 接口,调用 clone() 方法时会抛出此异常。

clone() 方法是 Object 类中定义的,用于返回一个与当前对象相同的副本。在默认实现中,它是浅拷贝 ,意味着它会复制对象的基本数据类型字段,但如果对象包含引用类型的字段,那么这些字段依然指向原来的对象。

2.2 浅拷贝与深拷贝

浅拷贝(Shallow Copy) :拷贝对象时,对于基本类型的字段会进行复制,而对于引用类型的字段,会复制引用地址,也就是说,源对象和拷贝对象共享同一个引用。

解释:
在 Java 中,clone() 方法是 Object 类提供的一个原生方法。这个方法并不是直接通过构造函数来创建一个新的对象,而是通过底层的 内存复制 技术来快速创建一个与原对象相同类型的新对象。
Object 类的 clone() 方法默认会调用 native 实现,这个实现通过操作内存直接创建一个新的对象实例,并将原对象的字段内容复制到新的实例中。这意味着 clone() 方法创建的对象是一个浅拷贝,字段的值被复制,但如果字段是引用类型,那么新对象的字段仍然指向原对象的同一内存地址。

深拷贝(Deep Copy) :不仅复制对象本身,还会递归地复制对象中的所有引用类型字段,使得源对象和拷贝对象之间不再共享任何引用。

clone() 方法默认是进行浅拷贝的,如果需要实现深拷贝,则需要重写 clone() 方法并手动处理引用类型字段的复制。

2.3 总结

总结

  • clone() 是通过 Object 类的 clone() 方法实现的,底层通过内存复制技术创建新对象。
  • clone() 会复制原对象的字段值,对于基本类型字段是值复制,对于引用类型字段是引用复制。
  • clone() 返回的是一个新对象,但新对象与原对象的引用类型字段指向同一内存地址,属于浅拷贝。
  • 调用 clone() 不会触发构造函数的执行。

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/5820.html

(0)
LomuLomu
上一篇 2025 年 1 月 11 日 下午5:03
下一篇 2025 年 1 月 11 日 下午6:04

相关推荐

  • 手动部署前后端分离的项目到本地

    1.准备工作 使用maven打包springboot项目为.jar文件得到springboot-0.0.1-SNAPSHOT.jar 打包vue项目 npm install -g @vue/cli安装Vue CLI 在项目根目录下,运行npm run build命令来构建项目得到一个dist文件夹 将打包好的文件通过远程仓库中转至docker虚拟机 在虚拟机…

    2025 年 1 月 12 日
    49100
  • 一款基于 Vue + SpringBoot 前后端分离的开源博客系统!

    大家好,我是Java领域的技术爱好者。 今天,我将向您展示一个采用Vue和SpringBoot技术栈构建的开源博客系统——拾壹博客! 项目概览 拾壹博客(shiyi-blog)是一个现代化的前后端分离博客系统,支持本地文件存储和七牛云存储,集成了QQ、微信等第三方登录,并具备即时通讯聊天室功能。 核心功能亮点: 采用前后端分离架构,运用前沿技术打造 Mark…

    2024 年 12 月 26 日
    38700
  • 【2024最新版可用】Intellij IDEA破解教程,附IDEA激活码

    IntelliJ IDEA 是一种广受欢迎的 Java 集成开发环境,被认为是最佳的 Java 开发工具之一。本文将分享如何通过脚本免费激活 IDEA 及 Jetbrains 全家桶工具,支持 2021 及以上版本,包括最新版本。 一、下载并安装 IDEA 首先,前往 JetBrains 官网下载最新版本的 IDEA。安装过程非常简单,按照提示一步步操作即可…

    未分类 2024 年 7 月 15 日
    2.0K00
  • 微软开源!Office 文档轻松转 Markdown!

    大家好,我是 Java陈序员。 今天,给大家介绍一款微软开源的文档转 Markdown 工具。 关注微信公众号:【Java陈序员】,获取开源项目分享、AI副业分享、超200本经典计算机电子书籍等。 项目介绍 MarkItDown —— 微软开源的 Python 工具,能够将多种常见的文件格式(如 PDF、PowerPoint、Word、Excel、图像、音频…

    2025 年 1 月 15 日
    32700
  • 【JVM】使用 IntelliJ IDEA 进行 Java 内存分析

    使用 IntelliJ IDEA 进行 Java 内存分析 前言 内存管理对于 Java 应用程序的性能至关重要,特别是在处理复杂的应用程序时,内存泄漏或内存溢出等问题可能导致性能下降甚至程序崩溃。在遇到这些问题时,内存分析工具能够帮助开发者快速定位和解决问题。IntelliJ IDEA 提供了内置的内存分析工具,可以方便地捕获并分析 Java 应用程序的内…

    未分类 2024 年 12 月 31 日
    82500

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信