Java 对象比较,equals和==的比较结果

1.看下面的代码,输出什么呢?

Integer n1 = new Integer(127);
Integer n2 = new Integer(127);
System.out.println("n1 == n2:" + (n1 == n2));//false

Integer n3 = 127;
Integer n4 = 127;
System.out.println("n3 == n4:" + (n3 == n4));//true

Integer n5 = new Integer(128);
Integer n6 = new Integer(128);
System.out.println("n5 == n6:" + (n5 == n6));//false

Integer n7 = 128;
Integer n8 = 128;
System.out.println("n7 == n8:" + (n7 == n8));//false

输出结果:
n1 == n2:false
n3 == n4:true
n5 == n6:false
n7 == n8:false

首先我们知道“==”比较的不是对象的值,而是对象的引用。
那么n1==n2 和 n5==n6 返回false,这很好理解,因为都是通过new创建的不同对象。
但是为什么n3==n4返回true,而n7==n8返回false呢?

是这样的:

-128 ~ 127 这些数字会在内存里长期缓存,如果有哪个变量的值是处于这期间的(包含-128和127),都会从这缓存里取,所以取到的是同一个。

总结一下,对于下列包装对象的两个实例,当它们的基本值相同时,他们用==比较总是返回true:
Boolean
Byte
Character, \u0000 - \u007f(7f是十进制的127)
Integer(-128 ~ 127)
Short (-128 ~ 127)
Long (-128 ~ 127)

2.如果想比较两个对象的实际内容是否相同,如何操作呢?
用对象的通用比较方法:equals()方法。
上面的n1~n8任意两个对象之间用equals方法比较,返回的都是true。

3.但是注意,equals()方法不能用于基本类型。比如下面这样是不行的,因为equals()方法是类的方法。
int a = 1;
int b = 1;
System.out.println(a.equals(b)); //编译不通过

4.用equals()来比较对象内容是否相同,是不是适用于所有的类呢?答案是并非适用于所有的类。
看下面的例子:

class Value {
    int i;
}

public class CompareMethod{
    public static void main(String[] args) {
        Value v1 = new Value();
        Value v2 = new Value();
        v1.i = v2.i = 100;
        System.out.println(v1.equals(v2));
    }
}

输出为false!是的,为什么和上面第二步的结果不一样呢?

因为Java类的equals()方法默认的行为也是比较引用。参见Java Object类的equals()方法:

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

而上面用到的Integer类里其实是覆盖了equals()方法的,覆盖后它被用来比较内容。而我们自定义的Value类并没有覆盖equals()方法,用的还是Object类的equals()方法。

(大多数java类库都覆盖了equals方法,用来比较对象内容而非对象的引用。)

所以,要想让我们自定义的类在比较内容时表现出我们想要的样子,就得覆盖equals()方法。

4.下面以String类为例看看效果。String类本身已经重写了equals方法,重写后的equals方法用来比较内容。
如果在一个方法里,定义了如下三个字符串:

        String A = "hello";
        String B = new String("hello");
        String C = new String(A);

那么,下面的输入是什么呢?

        System.out.println("A.equals(B):" + A.equals(B));
        System.out.println("A.equals(C):" + A.equals(C));
        System.out.println("B.equals(C):" + B.equals(C));
        System.out.println("A==B:" + (A==B));
        System.out.println("A==C:" + (A==C));
        System.out.println("B==C:" + (B==C));

首先我们要知道,String类已经重写了equals方法,重写后的equals方法用来比较内容,参见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;
    }

因为String类的equals方法比较的是值,所以equals比较当然返回true。而A,B,C是三个不同的对象,所以其地址是不同的,用==比较,返回的是false。
答案:
A.equals(B):true
A.equals(C):true
B.equals(C):true
A==B:false
A==C:false
B==C:false

上面要注意的是:new String(“hello) 和new String(A)有什么区别吗?
这两个传入的都是字符串“hello”,调用的构造方法也是同一个:

    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

因此没有什么区别,都会创建一个新的字符串对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值