==和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培训机构。

    相关文章

      网友评论

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

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