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

xiaoxiao2021-02-28  91

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

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

转载请注明原文地址: https://www.6miu.com/read-58398.html

最新回复(0)