你还记得java核心基础类Object么?

Object 类的常见方法有哪些?

Object 类是一个特殊的类,是所有类的父类。它主要提供了以下 11 个方法:

/**
* 尚硅谷2024新版3小时速通Docker教程
* https://www.sanzhishu.top/2696.html
*/

// native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写
public final native Class<?> getClass()

// native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的 HashMap
public native int hashCode()

// 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等
public boolean equals(Object obj)

// native 方法,用于创建并返回当前对象的一份拷贝
protected native Object clone() throws CloneNotSupportedException

// 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法
public String toString()

// native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个
public final native void notify()

// native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程
public final native void notifyAll()

// native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间
public final native void wait(long timeout) throws InterruptedException

// 多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒
public final void wait(long timeout, int nanos) throws InterruptedException

// 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
public final void wait() throws InterruptedException

// 实例被垃圾回收器回收的时候触发的操作
protected void finalize() throws Throwable { }

== 和 equals() 的区别

  • == 对于基本类型和引用类型的作用效果是不同的:

    • 对于基本数据类型来说,== 比较的是值。
    • 对于引用数据类型来说,== 比较的是对象的内存地址。 Java 只有值传递,所以对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是值,只是引用类型变量存的值是对象的地址。
  • equals() 不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。equals()方法存在于Object类中,而Object类是所有类的直接或间接父类,因此所有的类都有equals()方法。equals() 方法存在两种使用情况:

    • 类没有重写 equals()方法:通过equals()比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是 Object类equals()方法。
    • 类重写了 equals()方法:一般我们都重写 equals()方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true,即认为这两个对象相等。String 中的 equals 方法就是被重写过的。

hashCode() 是什么?返回值是内存地址吗?

  1. hashCode方法用于返回对象的哈希码(散列码)值,hashCode值是一个整数值,这个方法可以提高哈希表(如Hashtable提供的哈希表)的性能,确定该对象在哈希表中的索引位置。

  2. hashCode() 定义在 Object 类中,这就意味着 Java 中的任何类都包含有 hashCode() 函数。hashCode在Object类中有native修饰,是本地方法,该方法的方法体不是Java实现的,是由C/C++实现的,最后编译为.dll文件,然后由Java调用。

  3. hashCode 可以是内存地址,也可以不是内存地址,在 Oracle OpenJDK8 中有六种生成方式来生成 hashCode,默认使用的是一种随机数生成的方法,这是由于垃圾回收时对象需要发生移动,因此使用内存地址会带来不便。

为什么要有 hashCode()?

Java的集合有两类,一类是 List,还有一类是 Set。前者有序可重复,后者无序不重复。当我们在Set中插入的时候怎么判断是否已经存在该元素呢,可以通过equals方法。但是如果元素太多,用这样的方法就会比较慢。

于是有人发明了哈希算法来提高集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储的那个区域。

hashCode 方法返回的就是一个哈希码值,当集合要添加新的元素时,先调用这个元素的 hashCode 方法,就一下子能定位到它应该放置的位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的 equals 方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。这样一来实际调用 equals 方法的次数就大大降低了,相应就大大提高了执行速度。

hashCode() 和 equals() 都是用于比较两个对象是否相等。

  • 那为什么 JDK 还要同时提供这两个方法呢?

    这是因为在一些容器(比如 HashMap、HashSet)中,有了 hashCode() 之后,判断元素是否在对应容器中的效率会更高。我们在前面也提到了添加元素进HashSet的过程,如果 HashSet 在对比的时候,同样的 hashCode 有多个对象,它会继续使用 equals() 来判断是否真的相同。也就是说 hashCode 帮助我们大大缩小了查找成本。

  • 那为什么不只提供 hashCode() 方法呢?

    这是因为两个对象的hashCode 值相等并不代表两个对象就相等。

  • 那为什么两个对象有相同的 hashCode 值,它们也不一定是相等的?

    因为 hashCode() 所使用的哈希算法也许刚好会让多个对象传回相同的哈希值。越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓哈希碰撞也就是指的是不同的对象得到相同的 hashCode)。

为什么重写 equals() 时必须重写 hashCode() 方法?

之前在 HashSet 检查元素重复的过程中,判断的过程是:

  • 如果两个对象的hashCode 值相等,那这两个对象不一定相等(哈希碰撞)。
  • 如果两个对象的hashCode 值相等并且equals()方法也返回 true,我们才认为这两个对象相等。
  • 如果两个对象的hashCode 值不相等,我们就可以直接认为这两个对象不相等。

如果重写 equals() 时没有重写 hashCode() 方法的话,就可能会导致 hashCode 值却不相等被判断为不同的对象,但是事实上两个对象是重复的(equals 为 true)。

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值