所有对象都通用的方法

本文深入探讨Java中equals方法实现等价关系的原则和注意事项,包括自反性、对称性、传递性、一致性及非空性。同时阐述了在实现equals方法后,必须重写hashCode方法以确保哈希散列的正确性。此外,文章还详细介绍了clone方法的正确使用方式,强调了使用super.clone获取实例的重要性,以及实现Cloneable接口的必要性。最后,通过示例代码演示了浅层复制和深层复制的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、equals方法

(一)、equals提供了实现等价关系

1、自反性:对于非null的引用值x,x.equals(x)返回true,所以重写equals是会写

  public boolean equals(Object o) {
        if (o == this)
            return true;
        ....
 }

2、对称性,如果x.equals(y)返回true,则y.equals(x)也返回true

package jdk.learn;

import java.sql.Timestamp;
import java.util.Date;

/**
 * Created by yesh on 2015/4/6.
 */
public class TestTimestamp {
    public static void main(String[] args) {
        testEquals();
    }

    /***
     * Timestamp违反了equals中的对称行,所以Timestamp类中
     * 有个免责声明,不要将Date和Timestamp混用
     * 输出结果:false,true
     */
    public static void testEquals(){
        Date date = new Date();
        Timestamp timestamp = new Timestamp(date.getTime());
        System.out.println(timestamp.equals(date));
        System.out.println(date.equals(timestamp));
    }
}
注:Timestamp违反了equals的原则,所以使用的时候要注意。

3、传递性,非null的x,y,z如果x.equals(y)和y.equals(z),则x.equals(z)。

4、一致性:相等的对象永远相等,不相等的对象永远不相等。

5、非空性:所有的对象都不能等于null

所以在重新equals的时候:

        if(date==null){
            return false;
        }
        if(date instanceof Date){ //使用instanceof就可以省掉判断null
            return false;
        }
注:使用给了instanceof 就不需要使用date==null的方式

(二)、注意点

1、当写完了equals方法后一定要判定,是否遵守这5个等价关系,如果没有就要进行修正。

2、要覆盖hashCode方法

不重写hashCode方法后,对进行equals是没有影响的,但是对使用Hash散列会出现预想不到的结果。

package jdk.learn;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * Created by yesh on 2015/4/6.
 */
public class TestHashCode {

    public static void main(String[] args) {
        Map map = new HashMap();
        PhoneNumber phoneNumber = new PhoneNumber("123456789");
        map.put(phoneNumber,"yezi");
        System.out.println(map.get(phoneNumber)); //取出的值为null
        PhoneNumber phoneNumber1 = new PhoneNumber("123456789");
        System.out.println(phoneNumber.equals(phoneNumber1)); //输出true
    }

    static class PhoneNumber{
        private String number;
        public PhoneNumber(String number) {
            this.number = number;
        }

        @Override
        public boolean equals(Object obj) {
            if(!(obj instanceof PhoneNumber)){
                return false;
            }
            PhoneNumber phoneNumber1 = (PhoneNumber)obj;
            if(this.number==null&&this.number==null){
                return true;
            }
            return this.number.equals(phoneNumber1.number);
        }

        @Override
        public int hashCode() {
            Random random = new Random();
            int hashCode = random.nextInt(100);
            return hashCode;
        }
    }
}

二、clone方法

1、clone的对象应该有super.clone获取,不应该使用new来创建。

在源码中BitSet的clone方法中获取:BitSet result = (BitSet) super.clone();后接着对内部的数据调用clone方式。

2、实现接口Cloneable

3、注意浅层复制和深层复制的关系。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值