java 中的 equals 和 == 

java 中的 equals 和 == 

本文的文章结构如下,尽可能让大家对 equals 和 == 掌握通透,如有错误之处,欢迎在评论区指出:

一、Java 的数据类型分类(简)

一、equals 和 == 区别

二、String 的 equals 和 == 

三、Integer 的 equals 和 ==

 

一、java 的数据类型(简)

Java 中的数据类型分为【基本数据类型(原始数据类型8种)】和【引用数据类型】

基本数据类型:byte、short、char、int、long、float、double、boolean

引用数据类型:继承于Object,如String等

二、equals 和 == 区别

==:

  1. 可用于基本数据类型的变量,也可比较引用类型的变量
  2. 作用于基本数据类型的变量,直接比较存储的“值”是否相等
  3. 作用于引用类型的变量,比较的是所指向对象的地址是否相等,确切地说:是堆内存地址。

equals:

  1. 只用于引用类型的变量,不能用于基本数据类型的变量
  2. 是根据 Object 的equals() 方法来进行比较,如果没有对 equals 方法进行重写,比较的是引用类型的变量所指向的对象的地址

这是因为:

Object 的 equals() 方法如下,所以

public boolean equals(Object obj) {
    return (this == obj);
}

综上,equals 比较主要是调用对象的 equals() 方法,所以我们只需要看对象类的 equals() 是怎么写的即可知道,后文我们分别从 Integer 和 String 两种对象来看 equals() 的结果。

三、String 的 equals 和 == 

String 的 equals() 方法重写为:比较字符串的内容

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = length();
            if (n == anotherString.length()) {
                int i = 0;
                while (n-- != 0) {
                    if (charAt(i) != anotherString.charAt(i))
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

所以,对于 String 来说:

  • ==:比较的是两个字符串内存地址(堆内存)的数值是否相等,数据数值比较;
  • equals():比较的是两个字符串的内容,数据内容比较

大家可以判断以下代码的输出结果吧:

String str1 = "Hello";
String str2 = new String("Hello");
String str3 = str2; // 引用传递
System.out.println(str1 == str2); // false
System.out.println(str1 == str3); // false
System.out.println(str2 == str3); // true
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
System.out.println(str2.equals(str3)); // true

另外一个相关的知识点(不常用),intern() 方法,是一个 native 的实现。

String s1 = "Hello";
String s2 = new String("Hello");
s2 = s2.intern();
System.out.println(s1 == s2);       //  true
System.out.println(s1.equals(s2));  //  true

intern() 的返回值是字符串"Hello",它内部的判断为:检查常量池中是否存在“Hello”字符串,如果存在,返回常量池的“Hello”的引用,如果不存在,会将“Hello”添加到常量池中,再返回它的引用,因此经过 intern() 操作后,s2 和 s1 的引用相等。

四、Integer 的 equals 和 == 

Integer 的情况是怎么样呢?我们去看 Integer 的 equals() 方法。

/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
       return value == ((Integer)obj).intValue();
    }
    return false;
}

/**
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
public int intValue() {
   return value;
}

Interger 的 equals() 方法返回其基本类型变量的值,intValue() 方法返回的是 Integer 的值。

另外需要注意的是:如果 obj 为一个基本数据类型,则编译器会自动将 obj 装箱进行比较,比如:i.equals(5);  5 -> new Integer(5) (??? 这里的装箱应该不是新建一个实例?那内部是怎么样呢?)

若直接入参是非相同类型的对象,则直接会返回 false。

基本类型的包装类型 equals() 总结:
1. equals() 参数为基本数据类型,则编译器会进行自动装箱为包装类型,0-> 默认为 Integer,而不是 Long,注意!。
2. equals() 参数为包装类型,则先比较是否为同类型,非同类型直接返回 false,同类型再比较值。

练习:

new Long(0).equals(0);//false, 参数 int ,装箱为 Integer 类型,不同类型直接返回false
new Integer(500).equals(500);// true,相同类型,比较值相等
Integer a = new Integer(500);
Integer b = new Integer(500);
a.equals(b);//true

基本数据类型及其包装类型的 == :
1. 基本类型==包装类型
    1) 同类型,编译器自动拆箱,比较值:如Integer 与int,Long与long进行==比较时,会自动拆箱为基本类型
    2) 不同类型,会自动拆箱且向上转型比较值(低级向高级是隐式类型转换如byte<short<int<long<float<double,高级向低级必须强制类型转换,可能会有溢出)
3. 两边都是包装类型,比较引用地址,注意 IntegerCache 除外。IntegerCache 用于 Integer.valueOf() 方法,若是 -128-127 的大小,会返回相同的对象,而不是新建对象。

// IntegerCache.low = -128,IntegerCache.high = 127
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
       return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

好了,我们用这几条规则做一下这几道题吧。

Integer a = 59;
Integer b = Integer.valueOf(59);
Integer c = new Integer(59);
     
System.out.println(a == b);  //true 因为59位于缓存区间直接从缓存中获取
System.out.println(a == c);  //false
System.out.println(b == c);  //false
 

Integer a1 = 200;
Integer b1 = Integer.valueOf(200);
Integer c1 = new Integer(200);
         
System.out.println(a1 == b1);  //false 因为200超出缓存区间从新创建对象
System.out.println(a1 == c1);  //false
System.out.println(b1 == c1);  //false

以上就是 Java 中的 equals() 和 == 的比较。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heidiwang0000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值