zoukankan      html  css  js  c++  java
  • equals与“==”之惑

    Java中存在两种判断相等的方式,一个采用运算符“==”进行判断,另一个是采用equals方法进行判断。一直对这两种判断方式感到十分迷惑,最近有空好好研究了一番。

    ==”操作符比较的是两个变量的值是否相等,对于对象的引用则表示的是对象在堆中存储的地址是否相等。

    equals方法是Object的一个方法,对于没有重写这个方法的类来说,equals方法的作用和“==”是一样的,因为这个方法就是用“==”来实现的。对于重写了这个方法(Java Api中的绝大部分类也这么做了)的类来说,那么功能就与“==”不同了,一般来说,equals方法表示的是两个引用是否是同一个对象的引用,即比较的是对象的内容是否相同。

    下面,分类型来说说“==”与equals方法的用法。

    1、  简单基本类型之间的比较

    对于简单基本类型之间的比较来说,只能使用“==”运算符,其含义也是显而易见的,就是比较两个值是否相等,在此不多做解释。

    2、  简单对象之间的比较

    此处的简单对象指的是那些自定义的,但是未重写equals方法的类的实例。对于这类的equals方法的作用是与“==”相同的,比较的是两个对象的地址是否相同。下面是我写的测试代码:

    publicclass Test1 {

     

    }

     

    publicclass Test2 {

        publicstaticvoid main(String[] args) {

          

           Object obj1 = new Object();

           Object obj2 = obj1;

           Object obj3 = new Object();

           System.out.println("obj1 == obj2: " + (obj1 == obj2));

           System.out.println("obj1.equals(obj2): " + obj1.equals(obj2));

           System.out.println("obj1 == obj3: " + (obj1 == obj3));

           System.out.println("obj1.equals(obj3): " + obj1.equals(obj3));

           

           Test1 test11 = new Test1();

           Test1 test12 = test11;

           Test1 test13 = new Test1();

           System.out.println("test11 == test12: " + (test11 == test12));

           System.out.println("test11.equals(test12): " + test11.equals(test12));

           System.out.println("test11 == test13: " + (test11 == test13));

           System.out.println("test11.equals(test13): " + test11.equals(test13));

        }

     

    }

    输出结果为

    obj1 == obj2: true

    obj1.equals(obj2): true

    obj1 == obj3: false

    obj1.equals(obj3): false

    test11 == test12: true

    test11.equals(test12): true

    test11 == test13: false

    test11.equals(test13): false

    从中可以看出obj1obj2obj1obj3test11test12test11test13的比较结果是一样的,而且equals方法与“==”的比较结果是一样的。

    3、  String类型的比较

    对于String对象的equals方法比较的就是两个对象的内容是否相同,而“==”比较的依旧是两对象的地址是否相同。

    publicclass Test1 {

        publicstaticvoid main(String[] args) {

           String s1 = "Monday";

           String s2 = "Monday";

           String s3 = new String("Monday");

           System.out.println("s1 == s2: " + (s1 == s2));

           System.out.println("s1.equals(s2): " + s1.equals(s2));

          

           System.out.println("s1 == s3: " + (s1 == s3));

           System.out.println("s1.equals(s3): " + s1.equals(s3));

          

           s3 = s3.intern();

           System.out.println("after s3.intern()");

           System.out.println("s1 == s3: " + (s1 == s3));

           System.out.println("s1.equals(s3): " + s1.equals(s3));

        }

    }

     

    输出结果为:

       s1 == s2: true

       s1.equals(s2): true

       s1 == s3: false

       s1.equals(s3): true

       after s3.intern()

       s1 == s3: true

    s1.equals(s3): true

    从结果来看,s1s2应该引用的是同一个对象。原因是程序在运行的时候会创建一个字符串缓冲池,当使用String s1 = "Monday"创建对象时,程序会将s1放入到缓冲池中,而再用String s2 = "Monday"创建对象时,程序会首先查找池中的对象是否存在相同值的,如果存在,就返回池中对象的引用,不存在,则新建一个对象放入池中,并返回对象,这里显然返回的是s1创建的对象的应用,因此,第一行结果为true。又因为Stringequals方法比较的是内容,所以第二行的结果也是true。当使用String s3 = new String("Monday")创建对象时,是告诉程序不使用池中的具有相同内容的对象,直接新建一个对象,因此第三行为false,第四行为true,但是当执行s3.intern()后,程序会检查池中是否存在相同内容的对象,如果存在,则返回该对象的引用,如果不存在,则将对象放入池中,并返回该对象的引用,因此第五行和第六行都是true

     

     

    4、  简单基本类型与封装类之间的比较

    在这里,以intInteger为例进行说明。在jdk1.5以上的版本中基本类型与封装类型能够互相转化,与String类型的对象和字符串常量之间的比较类似。

    测试代码如下:

       publicclass Test1 {

        publicstaticvoid main(String[] args) {     

           int i = 1;

           Integer i1 = 1;

           Integer i2 = 1;

           Integer i3 = new Integer(1);

           Integer i4 = new Integer(1);

          

           System.out.println("i1 == i2: " + (i1 == i2));

           System.out.println("i1.equals(i2): " + i1.equals(i2));

          

           System.out.println();

           System.out.println("i3 == i4: " + (i3 == i4));

           System.out.println("i3.equals(i4): " + i3.equals(i4));

          

           System.out.println();

           System.out.println("i2 == i4: " + (i2 == i4));

           System.out.println("i2.equals(i4): " + i2.equals(i4));

          

           System.out.println();

           System.out.println("i == i2: " + (i == i2));

           System.out.println("i2.equals(i): " + i2.equals(i));

          

           System.out.println();

           System.out.println("i == i4: " + (i == i4));

           System.out.println("i4.equals(i): " + i4.equals(i));

          

        }

    }

     

    输出结果为:

       i1 == i2: true

       i1.equals(i2): true

     

       i3 == i4: false

       i3.equals(i4): true

     

       i2 == i4: false

       i2.equals(i4): true

     

       i == i2: true

       i2.equals(i): true

     

       i == i4: true

    i4.equals(i): true

     

    第一行和第二行说明,i1i2是引用了同一个对象,而且内容也相同。第三行和第四行说明i3i4引用了不同的对象,但是内容是相同的。第五行和第六行说明i2i4引用了不同的对象,但是内容是相同的。第七行和第八行说明经过i经过转型之后引用了i2引用的对象,而且内容相同。第九行和第十行,同样说明了经过i经过转型之后引用了i4引用的对象,而且内容相同。但是从第五行和第六行来看,i2i4是不同的对象,我的猜测是i在转型过程中引用了“==”右边引用的对象,看起来挺神奇的。

     

    好了,关于equals和“==”的研究就暂时先告一段落吧~~不对的地方请多多指正啊。

     

  • 相关阅读:
    服务器监控
    Ubuntu16.04安装印象笔记
    在vi中打开多个文件,复制一个文件中多行到另一个文件中
    Ubuntu16.04安装和卸载MySQL 5.7
    Ubuntu16.04 sever 安装
    查看ubuntu 各系统的内核版本
    Ubuntu16.04中查看硬盘的型号和读取速度
    python 实现3-2 问候语: 继续使用练习 3-1 中的列表,但不打印每个朋友的姓名,而为每人打印一条消息。每条消息都包含相同的问候语,但抬头为相应朋友的姓名。
    线程
    并发编程
  • 原文地址:https://www.cnblogs.com/unpolishedgem/p/2459002.html
Copyright © 2011-2022 走看看