zoukankan      html  css  js  c++  java
  • ==和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李懿老师

  • 相关阅读:
    数字图像、灰度直方图、色彩空间
    编译原理
    Visual studio文件中不同图标对应对象的类别
    230 前端之JQuery:JQuery属性操作
    229 前端之JQuery:JQuery基本语法
    228 前端之JavaScript:JS之DOM对象三
    227 前端之JavaScript:JS之DOM对象二
    226 前端之JavaScript:JS之DOM对象一
    225 前端之JavaScript:JavaScript对象
    021 用Vue.js搭建一个小说阅读网站
  • 原文地址:https://www.cnblogs.com/woniuxy/p/7419023.html
Copyright © 2011-2022 走看看