Java基础 - Object类常用方法

1、==与 equals() 的区别

  • ==运算符:
    1)作用于基本数据类型时,是比较两个数值是否相等;
    2)作用于引用数据类型时,是比较两个对象的内存地址是否相同,即判断它们是否为同一个对象;

  • equals()方法
    1)类没有覆盖/重写 equals() 方法时,则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象的内存地址是否相同。
    2)类覆盖/重写 equals() 方法时,一般会按照对象的内容来进行比较,若两个对象内容相同则认为对象相等,否则认为对象不等。

public class test1 {
   public static void main(String[] args) {
       String a = new String("ab"); // a 为⼀个引⽤
       String b = new String("ab"); // b为另⼀个引⽤,对象的内容⼀样
       String aa = "ab"; // 放在常量池中
       String bb = "ab"; // 从常量池中查找
       if (aa == bb) // true
             System.out.println("aa==bb");
       if (a == b) // false,⾮同⼀对象
             System.out.println("a==b");
       if (a.equals(b)) // true
             System.out.println("aEQb");
       if (42 == 42.0) { // true
             System.out.println("true");
       }
   }
}

说明:
1)String 中的 equals ⽅法是被重写过的,因为 object 的 equals ⽅法是比较的对象的内存地址,⽽ String 的 equals ⽅法比较的是对象的值。
2)当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。

2、hashCode()和equals()的关系

1、hashCode()方法的作用是获取哈希码,也称为散列码,返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置
在这里插入图片描述
2、equals()方法的作用就是判断两个对象是否相等,再Object类中是通过判断对象间的内存地址来决定是否相同
在这里插入图片描述
3、两者之间的关系
1)hashCode()主要用于提升查询效率提高哈希表性能,来确定在散列结构中对象的存储地址,在线性表中没有作用。
2)重写equals()必须重写hashCode();
3)若两个对象equals()比较返回true,那么它们的hashCode值一定也相同;
4)若两个对象equals()比较返回false,那么它们的hashCode值一定不相同;
5)如果两个对象的HashCode值相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置;
6)同一对象在执行期间若已经存储在集合中,则不能修改影响hashCode值的相关信息,否则会导致内存泄露问题。

3、重写equals()方法时通常为什么也要重写一下hashCode()方法?

首先看一下String类的源码:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
    }


public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }

1、Object类提供的equals()方法默认是用==来进行比较的,也就是说只要两个对象是同一个对象时,才能返回相等的结果。而在实际的场景中,通常是只要内容相同,就认为他们是相等的。所以在实际的情况下,Object类中提供的equals()方法默认实现是没有实用价值的,所以通常都要重写equals()方法。

2、由于hashCode()与equals()具有联动关系:
1)在Java中,Set接口代表无序的、元素不可重复的集合,HashSet则是Set接口的典型实现。

2)当向HashSet中加入一个元素时,它需要判断集合中是否已经包含了这个元素,从而避免重复存储。由于这个判断十分的频繁,所以要讲求效率,绝不能采用遍历集合逐个元素进行比较的方式。实际上,HashSet是通过获取对象的哈希码,以及调用对象的equals()方法来解决这个判断问题的。

3)HashSet首先会调用对象的hashCode()方法获取其哈希码,并通过哈希码确定该对象在集合中存放的位置。假设这个位置之前已经存了一个对象,则HashSet会调用equals()对两个对象进行比较。若相等则说明对象重复,此时不会保存新加的对象。若不等说明对象不重复,但是它们存储的位置发生了碰撞,此时HashSet会采用链式结构在同一位置保存多个对象,即将新加对象链接到原来对象的之后。之后,再有新添加对象也映射到这个位置时,就需要与这个位置中所有的对象进行equals()比较,若均不相等则将其链到最后一个对象之后。

4)为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,equals()方法重写时,通常也要将hashCode()进行重写,使得这两个方法始终满足相关的约定

4、final、finally、finalize 的区别?

1)final:可以作为修饰符修饰变量、方法和类,被final修饰的变量只能一次赋值;被final修饰的方法不能够在子类中被重写(override);被final修饰的类不能够被继承

2)finally用在异常处理中定义总是执行代码,无论try块中的代码是否引发异常,catch是否匹配成功,finally块中的代码总是被执行,除非JVM被关闭(System.exit(1)),通常用作释放外部资源(不会被垃圾回收器回收的资源)

3)finalize()方法是Object类中定义的方法,**当垃圾回收器将无用对象从内存中清除时,该对象的finalize()方法被调用。**由于该方法是protected方法,子类可以通过重写(override)该方法以整理资源或者执行其他的清理工作。
finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值