前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >探索对象的奥秘:解析Java中的Object类,有两下子!

探索对象的奥秘:解析Java中的Object类,有两下子!

原创
作者头像
bug菌
发布2024-07-02 00:06:38
1750
发布2024-07-02 00:06:38
举报
文章被收录于专栏:滚雪球学Java滚雪球学Java

  咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~


🏆本文收录于 **[「滚雪球学Java」 ](https://blog.csdn.net/weixin_43970743/category_9600553.html)专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅**!持续更新中,up!up!up!!

代码语言:java
复制
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

前言

  在Java中,所有的对象都是从Object类继承而来的。因此,理解Object类的属性和方法,对于熟悉Java编程语言至关重要。本文将介绍Object类的基本属性和方法,并解释它们在Java编程中的作用。

摘要

  本文以Java开发语言为例,详细介绍了Object类的基本属性和方法。其中,介绍了Object类的equals()方法、hashCode()方法和toString()方法的作用,以及如何重写它们以满足我们自己的需要。此外,还介绍了getClass()方法、wait()方法、notify()方法和notifyAll()方法的作用,在多线程编程中有重要的用途。

Object类方法介绍

Object类基本属性和方法

  在Java中,所有的类都是从Object类继承而来的。因此,Object类是Java中所有类的父类。Object类中包含了一些基本的属性和方法,用于操作对象.

equals()方法

  equals()方法用于比较两个对象是否相等。如果两个对象相等,即它们的引用指向同一个对象,或者它们的值相等,则equals()方法返回true,否则返回false。对于自定义的类,需要重写equals()方法以实现自定义的比较逻辑。

示例代码如下:

代码语言:java
复制
class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return name != null ? name.equals(person.name) : person.name == null;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }

    public String getName() {
        return name;
    }
}

public class TestEquals {
    public static void main(String[] args) {
        Person person1 = new Person("Alice");
        Person person2 = new Person("Alice");
        System.out.println("Equals Test: " + person1.equals(person2)); // 应该输出 true
    }
}

代码解析:

  根据如上案例代码,这里我给同学们做个解读:这段代码演示了如何为自定义类Person重写equals()hashCode()方法,并提供了一个测试案例来验证重写的效果。

类定义分析:

  1. Person类包含一个私有字段name,用于存储人的名字。
  2. 类的构造函数接收一个字符串参数来初始化name字段。
  3. equals()方法被重写,以提供基于名字字段的相等性比较:
    • 首先检查是否是同一个对象的引用(this == obj)。
    • 然后检查传入的对象是否为null,或者是否与当前对象属于同一个类(getClass() != obj.getClass())。
    • 如果上述检查通过,则将传入的对象转换为Person类型,并比较name字段。
  4. hashCode()方法被重写,以提供基于名字字段的哈希码生成逻辑。如果name不为空,则返回name的哈希码,否则返回0。
  5. getName()方法返回name字段的值。

测试案例分析:

  1. TestEquals类中的main方法创建了两个Person对象person1person2,它们具有相同的name值("Alice")。
  2. 使用person1.equals(person2)调用equals()方法来比较这两个对象。由于equals()方法是基于name字段实现的,所以即使person1person2不是同一个对象引用,它们也应该被认为是相等的。
  3. 程序输出"Equals Test: true",表示两个Person对象被认为是相等的。

  这个测试案例演示了如何正确重写equals()方法,以确保对象的相等性不仅仅基于内存地址,而是基于对象的属性值。同时,这也展示了如何编写测试代码来验证自定义类的equals()方法是否按预期工作。

hashCode()方法

  hashCode()方法返回对象的哈希码,用于将对象存储到哈希表中。如果两个对象相等,则它们的哈希码也必须相等。因此,对于自定义的类,需要重写hashCode()方法以保证哈希表中存储的对象是按照自定义的比较逻辑排列的。

示例代码如下:

代码语言:java
复制
import java.util.HashMap;

public class TestHashCode {
    public static void main(String[] args) {
        HashMap<Person, String> map = new HashMap<>();
        Person person = new Person("Bob");
        map.put(person, "Value");

        Person samePerson = new Person("Bob");
        System.out.println("HashCode Test: " + map.containsKey(samePerson)); // 应该输出 true
    }
}

代码解析:

  根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用HashMap来存储键值对,并尝试检查一个具有相同属性的新对象是否已经被存储在HashMap中。

以下是代码的逐行解析:

  1. import java.util.HashMap; - 导入Java的HashMap类,这是一个基于哈希表的映射接口实现。
  2. public class TestHashCode { - 定义了一个名为TestHashCode的公共类。
  3. public static void main(String[] args) { - 定义了main方法,它是Java程序的入口点。
  4. HashMap<Person, String> map = new HashMap<>(); - 创建了一个HashMap实例,其键类型为Person,值类型为String
  5. Person person = new Person("Bob"); - 创建了一个Person对象,并通过构造函数初始化其名字属性为"Bob"。
  6. map.put(person, "Value"); - 将Person对象作为键,字符串"Value"作为值,存入HashMap
  7. Person samePerson = new Person("Bob"); - 创建了另一个Person对象,同样初始化其名字属性为"Bob"。
  8. System.out.println("HashCode Test: " + map.containsKey(samePerson)); - 尝试检查HashMap是否包含键为samePerson的条目。如果Person类正确地重写了equalshashCode方法,那么即使samePerson是一个新的对象实例,它也应该与之前存储的Person对象具有相同的属性,因此map.containsKey(samePerson)应该返回true
  9. } - 结束main方法。
  10. } - 结束TestHashCode类。

注意: 这段代码中Person类没有给出定义。如果Person类没有正确重写equalshashCode方法,那么即使两个Person对象具有相同的属性,map.containsKey(samePerson)也可能返回false,因为HashMap会使用对象的hashCode值来确定键的存储位置,而默认情况下,每个新对象的hashCode值都是不同的。

为了使代码按预期工作,Person类需要重写equals方法来比较对象的属性,以及hashCode方法来提供一致的哈希码。例如:

代码语言:java
复制
public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return name != null ? name.equals(person.name) : person.name == null;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}

这段额外的代码将确保Person对象的equalshashCode方法根据其name属性正确工作。

toString()方法

  toString()方法返回对象的字符串表示。默认情况下,toString()方法返回对象的类名和哈希码。对于自定义的类,需要重写toString()方法以返回自定义的字符串表示。

示例代码如下:

代码语言:java
复制
public class TestToString {
    public static void main(String[] args) {
        Person person = new Person("Charlie");
        System.out.println("ToString Test: " + person); // 使用默认的toString实现
        System.out.println("Custom ToString Test: " + person.toString()); // 使用自定义的toString实现
    }
}

代码解析:

  根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用System.out.println打印对象的字符串表示形式,包括使用默认的toString实现和自定义的toString实现。

以下是代码的逐行解析:

  1. public class TestToString { - 定义了一个名为TestToString的公共类。
  2. public static void main(String[] args) { - 定义了main方法,它是Java程序的入口点。
  3. Person person = new Person("Charlie"); - 创建了一个Person对象,并通过构造函数初始化其名字属性为"Charlie"。
  4. System.out.println("ToString Test: " + person); - 使用System.out.println打印字符串"ToString Test: "后跟person对象的字符串表示。由于没有显示调用toString方法,这里使用的是Person类继承自Object类的默认toString实现,它通常返回对象的类名和哈希码的无符号十六进制表示。
  5. System.out.println("Custom ToString Test: " + person.toString()); - 首先调用person对象的toString方法,然后使用System.out.println打印字符串"Custom ToString Test: "后跟toString方法的返回值。这里假设Person类重写了toString方法,提供了自定义的字符串表示。
  6. } - 结束main方法。
  7. } - 结束TestToString类。

注意: 这段代码中Person类没有给出定义。如果Person类没有重写toString方法,那么第二行打印语句将调用Object类的toString方法,而不是Person类的自定义实现。如果Person类重写了toString方法,那么第二行打印语句将显示自定义的字符串表示。

例如,如果Person类重写了toString方法,它可能看起来像这样:

代码语言:java
复制
public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    // 重写toString方法
    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }
}

在这个例子中,Person类的toString方法返回一个格式化的字符串,其中包含了Person对象的name属性。这样,当调用person.toString()时,它将返回如"Person{name='Charlie'}"的字符串,而不是默认的类名和哈希码表示。

getClass()方法

  getClass()方法返回对象的类类型。在Java中,类也是一个对象,因此可以使用getClass()方法获取类的类类型。

示例代码如下:

代码语言:java
复制
public class TestGetClass {
    public static void main(String[] args) {
        Person person = new Person("David");
        Class<?> cls = person.getClass();
        System.out.println("GetClass Test: " + cls.getName()); // 输出 Person
    }
}

代码解析:

  根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用getClass()方法获取对象的Class对象,并使用这个Class对象来获取类名。

  以下是代码的逐行解析:

  1. public class TestGetClass { - 定义了一个名为TestGetClass的公共类。
  2. public static void main(String[] args) { - 定义了main方法,它是Java程序的入口点。
  3. Person person = new Person("David"); - 创建了一个Person对象,并通过构造函数初始化其名字属性为"David"。
  4. Class<?> cls = person.getClass(); - 调用person对象的getClass()方法,获取其Class对象,并将其赋值给cls变量。这里的Class<?>表示cls是一个通配符类型,可以接受任何类型的Class对象。
  5. System.out.println("GetClass Test: " + cls.getName()); - 使用System.out.println打印字符串"GetClass Test: "后跟调用clsgetName()方法的结果。getName()方法返回Class对象所表示的类的全名,即Person
  6. } - 结束main方法。
  7. } - 结束TestGetClass类。

注意: 这段代码中Person类没有给出定义,但是它必须是一个有效的Java类。getClass()方法是一个实例方法,它返回表示该实例的运行时类的对象。getName()方法返回一个String,表示调用它的类或接口的完全限定名称。

  例如,如果Person类定义如下:

代码语言:java
复制
public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }
    // 其他方法...
}

  那么在TestGetClass类中的main方法执行时,person.getClass()将返回Person类的Class对象,cls.getName()将返回字符串"Person",最终控制台输出将是:

代码语言:java
复制
GetClass Test: Person
wait()方法、notify()方法和notifyAll()方法

  wait()方法、notify()方法和notifyAll()方法用于在多线程编程中实现线程间的协作。其中,wait()方法使线程进入等待状态,直到其它线程调用notify()方法或notifyAll()方法唤醒它;notify()方法和notifyAll()方法用于唤醒进入等待状态的线程。这三个方法只能在同步代码块中使用。

示例代码如下:

代码语言:java
复制
public class TestSynchronization {
    private boolean ready = false;

    public synchronized void prepare() {
        while (!ready) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public synchronized void start() {
        ready = true;
        notifyAll();
    }

    public static void main(String[] args) {
        TestSynchronization test = new TestSynchronization();

        Thread thread = new Thread(() -> {
            test.prepare();
            System.out.println("Ready!");
        });

        thread.start();

        try {
            Thread.sleep(1000); // 等待线程开始等待
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        test.start(); // 唤醒等待的线程
    }
}

代码解析:

  根据如上案例代码,这里我给同学们做个解读:这段Java代码演示了如何使用同步机制(synchronized)和等待/通知机制(wait/notify)来控制线程间的协作。以下是代码的逐行解析:

  1. public class TestSynchronization { - 定义了一个名为TestSynchronization的公共类。
  2. private boolean ready = false; - 在类中定义了一个私有成员变量ready,初始值为false,用来表示是否准备好开始执行。
  3. public synchronized void prepare() { - 定义了一个名为prepare的公共同步方法。synchronized关键字确保同一时间只有一个线程可以执行这个方法。
  4. while (!ready) { - 使用一个循环来检查ready变量是否为false。如果是,线程将等待。
  5. try { - 开始一个try块,用来捕获可能发生的InterruptedException
  6. wait(); - 调用当前线程的wait()方法,导致线程等待,直到被另一个线程调用notifyAll()唤醒。
  7. catch (InterruptedException e) { - 捕获InterruptedException异常,并在捕获后执行以下操作:
  8. Thread.currentThread().interrupt(); - 调用当前线程的interrupt()方法,这将线程的中断状态设置为true
  9. } - 结束catch块。
  10. } - 结束while循环。
  11. public synchronized void start() { - 定义了另一个名为start的公共同步方法。
  12. ready = true; - 将ready变量设置为true,表示现在可以开始执行。
  13. notifyAll(); - 调用当前对象的notifyAll()方法,唤醒在此对象上等待的所有线程。
  14. public static void main(String[] args) { - 定义了main方法,它是Java程序的入口点。
  15. TestSynchronization test = new TestSynchronization(); - 创建了TestSynchronization类的一个实例。
  16. Thread thread = new Thread(() -> { - 创建了一个新的线程,其任务是执行一个匿名内部类,该类调用test.prepare()方法。
  17. test.prepare(); - 在新线程中调用prepare方法,使线程等待。
  18. System.out.println("Ready!"); - 当prepare方法中的while循环退出后,打印"Ready!"。
  19. }); - 结束匿名内部类的声明。
  20. thread.start(); - 启动新线程。
  21. try { - 开始一个try块,用来捕获Thread.sleep可能抛出的InterruptedException
  22. Thread.sleep(1000); - 使当前线程(即主线程)休眠1秒,以便让新线程有时间进入等待状态。
  23. } - 结束try块。
  24. catch (InterruptedException e) { - 捕获InterruptedException异常。
  25. e.printStackTrace(); - 如果发生异常,打印堆栈跟踪。
  26. } - 结束catch块。
  27. test.start(); - 在主线程中调用start方法,设置readytrue并唤醒等待的线程。
  28. } - 结束main方法。
  29. } - 结束TestSynchronization类。

代码执行流程:

  • 主线程创建了一个TestSynchronization对象和一个线程。
  • 新线程开始执行并调用prepare方法,进入等待状态。
  • 主线程休眠1秒,确保新线程已经等待。
  • 主线程调用start方法,设置readytrue并唤醒新线程。
  • 新线程被唤醒,打印"Ready!"。

  这个例子展示了如何使用同步和等待/通知机制来控制线程的执行顺序。

自定义类中的Object类方法

  除了继承Object类中的属性和方法之外,每个Java类都可以重写Object类中的方法,以实现自定义的逻辑。

重写equals()方法

在自定义的类中重写equals()方法时,需要遵循以下原则:

  • 自反性:一个对象必须等于它本身。
  • 对称性:如果A等于B,则B等于A。
  • 传递性:如果A等于B,B等于C,则A等于C。
  • 一致性:如果两个对象没有改变,那么它们之间的相等关系就不应该改变。
  • 非空性:任何对象都不应该等于null。

  在重写equals()方法时,需要判断参数是否为null,是否是当前类的实例,以及是否满足自定义的比较逻辑。

重写hashCode()方法

  在自定义的类中重写hashCode()方法时,需要保证相等的对象有相等的哈希码。通常情况下,可以根据对象的属性计算哈希码,并将它们相加得到最终的哈希码。

重写toString()方法

在自定义的类中重写toString()方法时,需要返回自定义的字符串表示。

实现

1. Object类的实现

  在Java中,每个类都继承自Object类。这意味着,如果你创建了一个类,但没有显式地指定它的父类,那么它将自动继承Object类。

  Object类是一个非常简单的类。它只有一个无参构造方法,没有成员变量,只有一些方法。以下是Object类的声明:

代码语言:java
复制
public class Object {
   public Object() {}
   public native int hashCode();
   public boolean equals(Object obj) {
      return (this == obj);
   }
   protected native Object clone() throws CloneNotSupportedException;
   public String toString() {
      return getClass().getName() + "@" + Integer.toHexString(hashCode());
   }
   public final native void notify();
   public final native void notifyAll();
   public final native void wait(long timeout) throws InterruptedException;
   public final void wait(long timeout, int nanos) throws InterruptedException {
      if (timeout < 0) {
         throw new IllegalArgumentException("timeout value is negative");
      }
      if (nanos < 0 || nanos > 999999) {
         throw new IllegalArgumentException("nanosecond timeout value out of range");
      }
      if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
         timeout++;
      }
      wait(timeout);
   }
   public final void wait() throws InterruptedException {
      wait(0);
   }
   protected void finalize() throws Throwable { }
}

  在上面的代码中,我们可以看到Object类的构造方法,hashCode(),equals(),clone(),toString()等方法。

Java Object类位于java.lang包中。有想法的同学可以仔细去研读下。

在这里插入图片描述
在这里插入图片描述

2. equals()方法

  equals()方法是Object类中最重要的方法之一。它用于比较两个对象是否相等。以下是equals()方法的声明:

代码语言:java
复制
public boolean equals(Object obj)

  如果两个对象相等,那么equals()方法应该返回true。如果它们不相等,应该返回false。如果你没有覆盖equals()方法,那么默认实现将使用==运算符来比较两个对象的引用地址。

在实现equals()方法时,需要遵循以下几个原则:

  • 自反性:对于任何非空引用x,x.equals(x)应该返回true。
  • 对称性:对于任何非空引用x和y,如果x.equals(y)返回true,则y.equals(x)也应该返回true。
  • 传递性:对于任何非空引用x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,则x.equals(z)也应该返回true。
  • 一致性:对于任何非空引用x和y,如果没有修改它们之间的比较信息,则多次调用x.equals(y)应该返回相同的结果。
  • 非空性:对于任何非空引用x,x.equals(null)应该返回false。

以下是一个实现equals()方法的例子:

代码语言:java
复制
package com.demo.javase.day42;

/**
 * 实现equals()方法的例子
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/10/12 15:09
 */
public class MyClassToEquals {

    private int x;
    private int y;

    //重写equals()
    public boolean equals(Object o) {
        if (!(o instanceof MyClassToEquals)) { // 检查o是否是MyClassToEquals类型
            return false;
        }
        MyClassToEquals obj = (MyClassToEquals) o; // 强制转换为MyClassToEquals类型
        return obj.x == x && obj.y == y; // 比较x和y
    }
}

  在这个例子中,我们覆盖了equals()方法来比较MyClassToEquals对象的x和y变量。我们首先检查传入的对象是否是MyClassToEquals类型,然后将其转换为MyClassToEquals类型。最后,我们比较x和y的值。

  而对equals()源码来看,实现方式是非常简单粗暴的,通常并不推荐使用,因为在实际应用中,我们需要比较的是对象的内容是否相等,而不是仅仅比较它们的引用地址。正确的实现方式需要比较对象的每个属性是否都相等,包括它们的类型、值等。

在这里插入图片描述
在这里插入图片描述

  根据如上重写equals()方法后,我们可以进行示例测试。

测试代码如下:

代码语言:java
复制
package com.demo.javase.day42;

/**
 * 实现equals()方法的例子
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/10/12 15:09
 */
public class MyClassToEquals {

    private int x;
    private int y;

    //重写equals()
    public boolean equals(Object o) {
        if (!(o instanceof MyClassToEquals)) { // 检查o是否是MyClassToEquals类型
            return false;
        }
        MyClassToEquals obj = (MyClassToEquals) o; // 强制转换为MyClassToEquals类型
        return obj.x == x && obj.y == y; // 比较x和y
    }

    public static void main(String[] args) {

        MyClassToEquals myClassToEquals_1 = new MyClassToEquals();
        MyClassToEquals myClassToEquals_2 = new MyClassToEquals();
        myClassToEquals_1.x = 1;
        myClassToEquals_1.y = 2;

        myClassToEquals_2.x = 1;
        myClassToEquals_2.y = 2;

        System.out.println(myClassToEquals_1.equals(myClassToEquals_2));
    }

}

测试结果如下:

在这里插入图片描述
在这里插入图片描述

3. hashCode()方法

  hashCode()方法是Object类另一个重要的方法。它用于返回一个对象的哈希码。哈希码是一个整数,用于表示对象的状态。

  在Java中,哈希码通常用于在散列表中查找对象。如果你不重新实现hashCode()方法,它将返回对象的默认哈希码,该哈希码是根据对象的内存地址计算得出的。所以,如果两个对象的引用地址不同,它们的哈希码也会不同。

  为了正确地使用散列表,你需要重新实现hashCode()方法,并确保如果两个对象相等,它们的哈希码也相等。以下是hashCode()方法的声明:

代码语言:java
复制
public native int hashCode();

在重新实现hashCode()方法时,需要遵循以下原则:

  • 如果两个对象相等,那么它们的哈希码必须相等。
  • 如果两个对象不相等,它们的哈希码不需要相等。但是,如果哈希码相等,则需要调用equals()方法来检查这两个对象是否真的相等。

以下是一个实现hashCode()方法的例子:

代码语言:java
复制
package com.demo.javase.day42;

/**
 * 实现hashCode()方法的例子
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/10/12 14:54
 */
public class MyClassToHashCode {

    private int x;
    private int y;

    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }
}

  在这个例子中,我们重写了hashCode()方法以返回基于x和y变量的哈希码。我们使用31作为质数来生成哈希码。这里的关键在于使用质数,可以减少哈希码冲突的可能性。

测试结果如下:

在这里插入图片描述
在这里插入图片描述

  如果不重写hashCode()方法,则输出的是对象的默认哈希码,也就是对象在内存中的地址经过哈希算法处理后的值。演示截图如下:

在这里插入图片描述
在这里插入图片描述

4. toString()方法

  toString()方法是Object类的另一个重要方法。它用于返回一个对象的字符串表示形式。该字符串通常包含对象的类型和一些有用的信息。

  在Java中,toString()方法通常用于将对象转换为字符串。例如,如果你有一个Person类,你可以通过调用person.toString()来获取该Person对象的字符串表示形式。

以下是toString()方法的声明:

代码语言:java
复制
public String toString()

以下是一个实现toString()方法的例子:

代码语言:java
复制
package com.demo.javase.day42;

/**
 * 实现toString()方法的例子
 *
 * @author bug菌
 * @version 1.0
 * @date 2023/10/12 14:55
 */
public class MyClassToString {

    private int x;
    private int y;

    public String toString() {
        return "MyClass [x=" + x + ", y=" + y + "]";
    }


    public static void main(String[] args) {

        MyClassToString myClassToString = new MyClassToString();
        myClassToString.x = 1;
        myClassToString.y = 2;
        System.out.println(myClassToString.toString());
    }
}

  在这个例子中,我们重写了toString()方法以返回一个包含x和y变量的字符串。这个字符串可以让我们更好地理解MyClass对象的状态。

测试结果如下:

在这里插入图片描述
在这里插入图片描述

  如果对象没有重写 toString 方法,直接调用 toString 方法会输出对象的类名和内存地址的字符串表示。例如,一个没有重写 toString 方法的 Object 对象,调用 toString 方法会输出类似于以下形式的字符串:getClass().getName() + "@" + Integer.toHexString(hashCode())。演示结果如下:

在这里插入图片描述
在这里插入图片描述

代码拓展:

  如上段代码定义了一个名为MyClassToString的类。这个类有两个私有的整型变量xy,这里我给同学们解读下。

  toString()Object类的一个方法,所有的类都继承了Object类,可以重写这个方法。在这段代码中,toString()方法被重写了,返回一个字符串,其中包含了对象的属性xy的值。

  在main方法中,创建了一个MyClassToString的对象myClassToString,并给xy赋值为12。然后,通过调用toString()方法,将对象转换为字符串,并打印输出。输出结果为MyClass [x=1, y=2]。这段代码定义了一个名为MyClassToString的类。这个类有两个私有的整型变量xy

  toString()Object类的一个方法,所有的类都继承了Object类,可以重写这个方法。在这段代码中,toString()方法被重写了,返回一个字符串,其中包含了对象的属性xy的值。

  在main方法中,创建了一个MyClassToString的对象myClassToString,并给xy赋值为12。然后,通过调用toString()方法,将对象转换为字符串,并打印输出。输出结果为MyClass [x=1, y=2]

总结

  Java的Object类作为类层级结构的根基,为所有Java类提供了一个共同的起点。它所定义的方法,虽然数量不多,但每一个都扮演着至关重要的角色。理解这些方法的工作原理和使用场景,对于深入掌握Java语言和进行高效编程至关重要。

核心方法解析

  1. equals()**方法**:是判断对象等价性的标准。默认实现仅比较对象的内存地址,但通常我们需要根据对象的属性来比较。因此,合理重写此方法,以实现基于属性值的等价性判断,是面向对象编程中封装和抽象思想的体现。
  2. hashCode()**方法**:与equals()方法紧密相关,用于散列存储结构中快速定位对象。正确的实现能够保证在散列表等数据结构中,相等的对象具有相同的哈希码,从而提高查找效率。
  3. toString()**方法**:提供了对象的字符串表示形式,这在日志记录、调试和展示对象信息时非常有用。重写此方法可以提供更为直观和信息丰富的对象描述。
  4. getClass()**方法**:返回对象的Class对象,这不仅可以用来获取类的类型信息,也是反射机制的基础。
  5. wait()**、**notify()**和**notifyAll()**方法**:这三个方法是Java并发编程中的基础,通过它们可以实现线程间的协调和通信,是实现同步机制的关键。

实践中的注意事项

  • 在重写equals()hashCode()方法时,必须确保两者的一致性,即如果两个对象通过equals()方法比较结果为true,则它们的hashCode()值也必须相等。
  • toString()方法的重写应当提供足够的信息,以便于开发者理解对象的状态,但同时要注意信息的敏感性,避免泄露重要数据。
  • 在使用wait()notify()notifyAll()进行线程间通信时,必须在同步代码块中调用,并且要注意捕获和处理InterruptedException异常。

小结

  通过对Object类方法的深入理解,我们可以看到Java设计者对于对象基本行为的规范和约束。每个方法都有其特定的用途和适用场景。掌握这些方法的正确使用和重写,能够帮助我们写出更加严谨、高效的代码。在实际开发中,合理利用这些方法,可以提升代码的可读性、可维护性和性能。

  Java作为一种成熟的编程语言,其核心类的设计充满了哲学和智慧。Object类的方法虽然简单,但它们是构建复杂应用的基础。作为Java开发者,我们应当深入理解这些基础概念,并在实践中不断探索和应用,以达到更高的编程境界。

☀️建议/推荐你

  无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Java」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门Java编程,就像滚雪球一样,越滚越大,指数级提升。

  码字不易,如果这篇文章对你有所帮助,帮忙给bug菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。   同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!

📣关于我

  我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金等平台签约作者,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计30w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


--End

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 摘要
  • Object类方法介绍
    • Object类基本属性和方法
      • 自定义类中的Object类方法
      • 实现
        • 1. Object类的实现
          • 2. equals()方法
            • 3. hashCode()方法
              • 4. toString()方法
              • 总结
                • 核心方法解析
                  • 实践中的注意事项
                    • 小结
                    • ☀️建议/推荐你
                    • 📣关于我
                    相关产品与服务
                    对象存储
                    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档