Java中equals与“==”的区别详解 您所在的位置:网站首页 thinkupcomeupwith的区别 Java中equals与“==”的区别详解

Java中equals与“==”的区别详解

2024-06-21 02:27| 来源: 网络整理| 查看: 265

由于之前也没好好刻意去记二者的区别,但是发现经常会用到这些,有时自己也用错,于是特地再次总结记忆,若能帮助到你,就更好了! 想要熟练掌握equals与==的用法与区别,前提必须掌握基本数据类型和引用类型的概念,讲二者区别之前,先大概讲解一下基本数据类型和引用类型的概念,当然,有一定基础的朋友可直接略过!

基本数据类型和引用类型

八大基本数据类型:

Byte,short,int,long,double,folat,boolean,char . 其中byte占一个字节,short和char占两个字节,int,float占四个字节,double和long占8个字节,boolean只有true和false,这八种数据变量中直接存储值 注意:八大基本数据类型对应着各自的封装类型的包装类,提供了更多的方法,且不进行初始化时值默认为空(基本数据类型必须初始化),并且属于引用类型

引用类型:

引用类型主要是一些类、接口、数组 引用类型变量中存储的是地址,对应的地址存储数据

"=="和equals()方法的区别和联系

 "=="比较基本数据类型时比较的是表面值内容,而比较两个对象时比较的是两个对象的内存地址值

对于equals方法,注意:equals方法不能作用于基本数据类型的变量

如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容      简单概括就是:

== 在基本数据类型:值内容, 引用类型时:地址 equals 重写:值内容 , equals不重写:地址

equals()方法源码解析

源代码

* Compares this string to the specified object. The result is {@code * true} if and only if the argument is not {@code null} and is a {@code * String} object that represents the same sequence of characters as this * object. * * @param anObject * The object to compare this {@code String} against * * @return {@code true} if the given object represents a {@code String} * equivalent to this string, {@code false} otherwise * * @see #compareTo(String) * @see #equalsIgnoreCase(String) */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }

`  从源码中知道,equals()方法存在于Object类中,因为Object类是所有类的直接或间接父类,也就是说所有的类中的equals()方法都继承自Object类,而通过源码我们发现,Object类中equals()方法底层依赖的是==,那么,在所有没有重写equals()方法的类中,调用equals()方法其实和使用==的效果一样,也是比较的地址值,然而,Java提供的所有类中,绝大多数类都重写了equals()方法,equals方法进行了重写则是用来比较指向的对象所存储的内容是否相等,当然有兴趣的朋友可以自己自定义一个类【默认是没有重写equals()方法】去试着用equals方法体会体会!

几个例子试着检验一下自己 Integer aaa=new Integer(5); Integer bbb=new Integer(5); int a=10; int b=10; String str1=new String("justice"); String str2=new String("justice"); String str3; str3=str1; System.out.println(aaa==bbb); System.out.println(aaa.equals(bbb)); System.out.println(a==b); System.out.println(str1==str2); System.out.println(str1.equals(str2)); System.out.println(str1==str3); System.out.println(str1.equals(str3));

结果: false true true false true true true 分析:

aaa和bbb都是Integer封装类型,是不同的对象,变量存储地址, 所以==结果为false,equals为true

a和b都是基本数据类型,变量存储值,所以==为true,基本数据类型无equals方法

str1和str2都是String类型,属于引用类型,变量存储地址,所以==为false,equals为true

创建str3的时候,str3指向了str1,所以str1和str3的指向同一个地址,存储的数据自然相同,所以均为true

涉及内存中的常量池问题例子 String s1 = "abc"; String s2 = "abc"; System.out.println(s1.equals(s2)); System.out.println(s1 == s2); 答案是:true true

为什么第二个会是true呢?这就涉及到了内存中的常量池,常量池属于方法区的一部分,当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象"abc",第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。 既然了解了内存中的常量池,那分析一下下面str1==str2为 false 的原因 String str1 = new String(“abcd”); String str2 = new String(“abcd”);

str1==str2为 false 分析: 这里创建了两次对象,一次是在常量池中创建了对象"abc",一次是在堆内存中创建了对象str1,所以str1和str2的地址值不相等。

再来一个有意思的例子:

Integer a=100; Integer b=1000; Integer c=100; Integer d=1000; System.out.println(a==b); System.out.println(a==c); System.out.println(b==c); System.out.println(b==d);

结果为: false true false false 分析: 大家觉得a和c是不同的对象,所以地址不同,所以结果为false才对,但是定义一个Integer变量时,会默认进行Integer.valueOf(a)操作,方法的源码如下:

public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有