==和EQUALS()的区别

作者: 蜗牛学院 | 来源:发表于2017-08-29 16:37 被阅读74次

简单的一句话说明就是:

==比较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是这样操作的:

判断传入方法的字符串与当前字符串长度是否一致,如果不一致则没有必要再进行比较了,直接返回false

如果长度一致则把两个支付串转换成char数组,通过循环对两个数组中的同位元素进行比较,其中有任意一对同位元素不一致则中断循环,返回false

如果循环完成任然没有跳出循环,则在循环自然中断后返回true

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

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

String a="Test";

String b="Test";

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

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

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

(a = = b)===> true

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

String Pool

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

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

String a="test";

String b=new String("test");

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

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

if(a == 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_1和i_2的值进行一个修改看看

Integer i_1 = 128;

Integer i_2 = 128;

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

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

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的这种操作形式是调用Integer的valueOf方法,而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_1和i_2直接赋值这个范围时==返回为true,超出范围自然返回为false

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

文章原创。

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

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

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

蜗牛学院,一家有态度的IT培训机构。

相关文章

  • Java 比较相等

    Java Equals() 特性 Equals() 和 == 的区别 重写Equals方法 重写HashCode方法

  • java 中 String == 原理 equals 和

    == 和equals的区别

  • 【面试1】

    基础 1、equals和==(equals和==的区别)equals:是Object的一个方法,实现对象的比较;复...

  • HashCode和Equals的区别

    HashCode和equals的区别: String方法的equals方法和HashCode方法 String的H...

  • ==和equals

    ==和equals的区别: ==和equals方法都是用来比较两个变量/对象是否相等。 如果没有重写equals方...

  • == 和 equals() 区别

    解释 代码 重写equals方法

  • ==和equals区别

    基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boo...

  • ==和Equals区别

    ==和Equals区别 对于基本数据类型:(byte、short、char、int、float、double、lo...

  • ==和Equals区别

    对于基本数据类型:(byte、short、char、int、float、double、long、boolean),...

  • 微小知识点合集

    1、equals和equalsIgnorecase有什么区别? 在JAVA里面,牵扯到equals和equalsI...

网友评论

    本文标题:==和EQUALS()的区别

    本文链接:https://www.haomeiwen.com/subject/cozodxtx.html