Java 关于“==”与equals——以String类型,基本类型与包装类比较为例

1、== 与 equals

“==”:

  • “==” 是属于关系运算符,返回一个 boolean 类型的值。
  • 对于基本数据类型的比较,是直接比较值的大小。
  • 对于引用数据类型的比较,则对对象地址进行比较。

equals:

  • equals 是属于 Object 的一个方法。
  • 类没有覆盖 equals 方法时,会使用 Object 类的 equals 方法,因为 Object 类中的 equals 方法是直接 使用 “==” 运算符比较,所以没有覆盖 equals 情况下 “==” 与 equals 是一样的。
  • 类覆盖 equals 方法时,比较规则一般用于对象内容的比较,如果相等则两个对象相等。

Object 中 equals 方法源码:

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

2、String类型的比较

例1:

String s1 = "张三";
String s2 = new String("张三");
System.out.println(s1 == s2);		//false
System.out.println(s1.equals(s2));	//true

字符串直接赋值与使用 new 创建字符串实例进行比较

使用 “==” 比较地址,s1直接引用常量池中的对象,s2引用堆内存中创建的字符串实例,地址不同,所以结果为 false。

使用 equals 方法会比较对象的值,结果为 true。


String 中重写 equals 方法源码:

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;
}

3、基本数据类型与包装类直接的比较(以 int 与 Integer 为例)

例1:

Integer integer1 = new Integer(10);
Integer integer2 = new Integer(10);
System.out.println(integer1 == integer2);		//false
System.out.println(integer1.equals(integer2));	//true

通过 new 关键字创建两个 Integer 实例进行比较

使用 “==” 比较地址,结果为 false。

使用 equals 方法比较,根据 Integer 中的 equals 方法比较规则,会进行拆箱成 int 类型,然后与equals 调用者的 value 进行比较,所以本质上是 int 类型的比较,结果为true。


Integer中equals方法源码:

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

例2:

int i = 10;
System.out.println(integer1 == i);		//true
System.out.println(integer1.equals(i)); //true

通过 Integer 对象与 int 类型比较

使用 “==” 比较,Integer类型(包括new创建和直接赋值) 遇到 int 类型时 Integer 会自动拆箱,所以本质上是两个int类型比较,结果为true。

使用 equals 比较,如果 equals 方法传入的是 int 类型,则会进行自动装箱成Integer类型进行比较。

关于 Integer 中 equals 方法传入 int 类型:equals 方法接收一个 Object 类型的参数,如果传入的是 int 类型,则会自动装箱成 Integer 类型。

代码示例:

Object o = 10;	//Object类型接收一个int类型数据
System.out.println(o.getClass());

运行结果:

class java.lang.Integer

例3:

Integer i1 = 128;
Integer i2 = 128;
Integer i3 = 127;
Integer i4 = 127;
System.out.println(i1 == i2);		//false
System.out.println(i3 == i4);		//true
System.out.println(i1.equals(i2));  //true
System.out.println(i3.equals(i4));  //true

//Integer i1 = 128; 可以写成:Integer i1 = Integer.valueOf(128);

定义 Integer 类型接收 int 类型数据。

给 Integer 类型直接赋值 int 类型会自动装箱成 integer 类,在装箱过程中,如果值在[-128,127]范围内,则会直接返回 IntegerCache.cache 中缓存的对象,如果不在这个范围则会用过 new 关键字创建一个新的 Integer 对象。

所以,上述比较中

使用 “==” 比较,如果值在 [-128,127] 之间比较结果为 true,反之为 false。

使用 equals 比较会比较存储的值,结果为 true。


Integer 类 valueof 方法源码:

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

IntegerCache 源码:

private static class IntegerCache {
    
    
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
    
    
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
    
    
            try {
    
    
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
    
    
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {
    
    }
}



——THE END——

猜你喜欢

转载自blog.csdn.net/weixin_46022868/article/details/115398453