Java基础之Object通用方法

本文深入探讨Java中Object类的通用方法,包括equals(), hashCode(), toString()和clone()的实现原理与应用场景。通过实例说明equals()如何判断对象等价,hashCode()在集合类中的作用,toString()的默认行为及clone()的浅拷贝与深拷贝区别。

Object通用方法

1.equals()

(1)等价关系

五个条件:自反性  对称性  传递性  一致性  与null的比较

x.equals(null); // false;   x不是null对象

(2)等价于相等

  • 对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。
  • 对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。
Integer x = new Integer(1);
Integer y = new Integer(1);
System.out.println(x.equals(y)); // true
System.out.println(x == y);      // false

(3)实现

  • 检查是否为同一个对象的引用,如果是直接返回 true;
  • 检查是否是同一个类型,如果不是,直接返回 false;
  • 将 Object 对象进行转型;
  • 判断每个关键域是否相等。
@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        EqualExample that = (EqualExample) o;

        if (x != that.x) return false;
        if (y != that.y) return false;
        return z == that.z;
    }

2.hashCode()

等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价,这是因为计算哈希值具有随机性,两个值不同的对象可能计算出相同的哈希值。

HashSet 和 HashMap 等集合类使用了 hashCode() 方法来计算对象应该存储的位置,因此要将对象添加到这些集合类中,需要让对应的类实现 hashCode() 方法。

可以将每个域都当成 R 进制的某一位,然后组成一个 R 进制的整数。

R 一般取 31,因为它是一个奇素数,如果是偶数的话,当出现乘法溢出,信息就会丢失,因为与 2 相乘相当于向左移一位,最左边的位丢失。并且一个数与 31 相乘可以转换成移位和减法:31*x == (x<<5)-x,编译器会自动进行这个优化。

3.toString()

默认返回 ToStringExample@4554617c 这种形式,其中 @ 后面的数值为散列码的无符号十六进制表示。

4.clone()

(1)cloneable
clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。

clone() 方法并不是 Cloneable 接口的方法,而是 Object 的一个 protected 方法。Cloneable 接口只是规定,如果一个类没有实现 Cloneable 接口又调用了 clone() 方法,就会抛出 CloneNotSupportedException。

(2)浅拷贝
拷贝对象和原始对象的引用类型引用同一个对象。

(3)深拷贝
拷贝对象和原始对象的引用类型引用不同对象。

(4)clone()的替代方案
使用 clone() 方法来拷贝一个对象即复杂又有风险,它会抛出异常,并且还需要类型转换。Effective Java 书上讲到,最好不要去使用 clone(),可以使用拷贝构造函数或者拷贝工厂来拷贝一个对象。

 

 

 

 

 

 

### Java `Object` 类常用方法及用途 #### 方法一:`equals(Object obj)` 此方法用于比较两个对象的内容是否相等。默认情况下,该方法会检查两个对象的引用地址是否相同;通常子类会覆盖此方法来实现基于实例变量的实际内容对比逻辑[^1]。 ```java public boolean equals(Object obj) { return (this == obj); } ``` #### 方法二:`hashCode()` 返回对象的哈希码值。支持使用 `HashMap`, `HashSet` 等依赖于键散列的数据结构。当重写了 `equals()` 方法之后也应该相应地重写 `hashCode()` 方法以保持一致性[^4]。 ```java public int hashCode() { return System.identityHashCode(this); } ``` #### 方法三:`toString()` 返回表示当前对象的信息字符串形式,默认实现给出的是类似于 "包名@十六进制哈希码" 的格式。大多数时候建议根据业务需求自定义此类输出以便调试或日志记录之用[^3]。 ```java public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } ``` #### 方法四:`getClass()` 获取并返回调用者的运行时表示型 (`Class`) 对象。这有助于在程序执行期间动态查询类型信息,在反射编程中有重要作用。 ```java public final native Class<?> getClass(); ``` #### 方法五:`clone()` 创建并返回一个新的对象作为现有对象的一个副本。需要注意的是只有实现了 `Cloneable` 接口的对象才能成功复制自己,否则抛出异常。浅拷贝只会影响顶层字段而不涉及深层嵌套对象的状态复制。 ```java protected native Object clone() throws CloneNotSupportedException; ``` #### 方法六:`finalize()` 已废弃的方法,曾经是在垃圾收集器准备释放内存之前给对象最后一次清理资源的机会。现代做法推荐显式管理资源生命周期而不是依靠不确定性的终结机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值