zoukankan      html  css  js  c++  java
  • [JAVA]为什么==和equals总让新手迷惑? 详解 关系操作符 == 和 equals

    关系操作符==和 类的equals方法都可以用来比较两个类是否相同,但实际用起来却经常产生令JAVA新手迷惑的结果。

    先看一段示例代码:

    public class HelloWorld {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //System.getProperties().list(System.out);
            String str1 = new String("Hello world!");
            String str2 = new String("Hello world!");
            System.out.println("str1==str2:"+ (str1==str2));
            System.out.println("str1.equals(str2):"+str1.equals(str2));
        }
    }

    输出:

    str1==str2:false

    str1.equals(str2):true

    为什么都是对类进行比较,结果却不一样呢?当我们搞清楚两种比较方式的原理之后,问题就迎刃而解了。

    1、关系操作符 == 和 !=

    关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系。也就是说,==和!= 只比较两边的值是否相等。

    对于JAVA来说,一切都是对象,对于对象的操作都是通过引用实现的。

    str1和str2虽然内容都是"Hello world!",但却是通过两次new开辟出来了两块空间存放的,引用str1和str2指向的是不同的空间,也就是他们的地址是不一样的,所以 str==str2结果是false

    2、equals方法

    JAVA中所有的类都继承自Object基类,打开Object.java的源码可以看到equals方法的实现:

        public boolean equals(Object obj) {
            return (this == obj);
        }

    可以看到,Object.java中对equals的实现就是简单的用==对比一下。

    那为什么输出了 str1.equals(str2):true 呢,是不是String中对equals进行了重写?

    下面是String.java中equals方法的实现代码:

         * @see  #compareTo(String)
         * @see  #equalsIgnoreCase(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方法,它将字符串的每一个字符进行了比较,完全相同的字符串就会输出true。

    这就解释了  str1.equals(str2):true

    类似的情况还有Integer、Double、Long等,读者可以自行验证

    总结一下:

    1、关系操作符==和!= 比较的是两边的值

    2、equals方法如果未被重写则比较的是引用的地址(其实也是对值进行比较),如果被重写了那就具体情况具体分析了,诸如Integer、Double、Long等基本类型的封装类都重写了equals方法用来比较所指对象的内容

  • 相关阅读:
    DataGridView单元格内容自动匹配下拉显示
    C#中datagridviewz中SelectionMode的四个属性的含义
    Visual Studio效率神器——超级扩展ReSharper安装和破解
    vue优化(1) vuecli3/4 【图片压缩 】||【文件压缩】
    DownValues, UpValues, SubValues, 和OwnValues之间的区别?
    Leonid Shifrin 的书
    python newbie——蒙特卡罗法计算圆周率
    python newbie——PE No.1
    指尖上的数学
    瞎猫碰到死耗子
  • 原文地址:https://www.cnblogs.com/zhengxl5566/p/9645402.html
Copyright © 2011-2022 走看看