==和equals()的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了==和equals()的区别相关的知识,希望对你有一定的参考价值。

 

简单的一句话说明就是:

== 比较Stack中的值(引用数据类型stack中存放的是对象的堆内存地址)

equals() 通常被覆写为比较对象的值

 

那么==和equals()之间到底有什么具体的区别呢?

如果单从Object类或继承于Object没有做出任何覆写操作的类来看,==和equals()之间没有任何区别,equals方法由Object类提供,在Object中对equals的实现是这样的:

public boolean equals(Object o){

return this == o;

}

但事实是API中的大部分类为我们重写了equals方法,例如String中,equals方法就被覆写为了对值的比较,String中的equals是这样操作的:

  1. 判断传入方法的字符串与当前字符串长度是否一致,如果不一致则没有必要再进 行比较了,直接返回false
  2. 如果长度一致则把两个支付串转换成char数组,通过循环对两个数组中的同位元素进行比较,其中有任意一对同位元素不一致则中断循环,返回false
  3. 如果循环完成任然没有跳出循环,则在循环自然中断后返回true

由此可见,在String中的equals实际是在对字符串的每一个值进行比较

有时候==我们比较值的错觉,如下列情况:

 

String a="Test";

String b="Test";

if(a= =b) ===> true

 

结果确实是我们想要得到的true,似乎比较成功了,但是!

这是因为当创建任何字符串文字时,JVM首先在字符串池中搜索该文字,并且如果找到匹配项,那么同样的引用将被赋予新的String。因此,我们得到了

a = = b===> true

简而言之就是ab指向了相同的堆内存区

                       String Pool

     b -----------------> "test" <-----------------a

但是,==在以下情况下失败。

String a="test";

String b=new String("test");

if (a==b) ===> false

在这种情况下,new String("test")对于新的String将在堆内存区中创建新的引用赋予给b此时b所指向的内存地址与a指向不同
ifa == b===> false

                String Pool

     "test" <-------------------- a

 

                   Heap

     "test" <-------------------- b

 

 

那在Integer等包装类型又会如何呢:

我们不妨来看看下面这个实验

Integer i_1 = 1;

Integer i_2 = 1;

Integer i_3 = new Integer(1);

System.out.println(i_1.equals(i_2)); //true

System.out.println(i_1.equals(i_3)); //true

System.out.println(i_1 == i_2); //true

System.out.println(i_1 == i_3); //false

好了,看上去一切真相大白,这个结果和我们期望的一模一样,真是这样吗?我们把i_1i_2的值进行一个修改看看

Integer i_1 = 128;

Integer i_2 = 128;

System.out.println(i_1 == i_2);

这个结果出人意料的返回了false,这是什么原因?看看Integerequals方法实现过程

public boolean equals(Object obj) {

if (obj instanceof Integer) {

return value == ((Integer)obj).intValue();

}

return false;

}

这个方法告诉我们,Integer其实还是在用==做对象的比较,其中的value是一个int类型,Integer中定义value是这样的

private final int value;

这个方法毫无争议,它和String中的equals有相同的思想。

我们在看看Integer i_1 = 1这段代码,其实Integer i_1 = 1的这种操作形式是调用IntegervalueOf方法,而valueOf方法在Integer中的声明如下:

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high){

return IntegerCache.cache[i + (-IntegerCache.low)];

}

return new Integer(i);

}

不难发现,在某个范围内Intger直接从IntegerCache中取值,超出了这个范围则执行new Intger,而IntegerCache的范围正好是-128~127,因此,当Integer i_1i_2直接赋值这个范围时==返回为true,超出范围自然返回为false

 

所以当你不知道到底应该使用哪个方法时,使用.equals()总是更好的。

 

文章原创。

若转载,请注明出处:“来自蜗牛学院cto李懿老师”。

若没有按照以上注明出处,一经发现必追究。

作者:蜗牛学院CTO李懿老师

以上是关于==和equals()的区别的主要内容,如果未能解决你的问题,请参考以下文章

equals()和==到底有啥区别啊?

equals和==的区别

[转]Java中==和equals的区别,equals和hashCode的区别

equals和==的区别是啥?

Java里的equals和==的区别是否equals是比较内容,==是比较地址的?

==和equals()的区别