• ==和equals的深度分析


    • ==的分析

      1.对于基本数据类型,比较的是他们的具体内容是不是一样,跟他们的内存地址无关。举个栗子:

      public class Test{
      	
      	public static void main(String[] args) {
      		int i = 10;
      		double j = 10.0;
      		float m = 10.0f;
      		char k = 10;
      		boolean b = true;
      		
      		System.out.println(i == j);
      		System.out.println(i == m);
      		System.out.println(m == k);
      		System.out.println("*******************");
      		//System.out.println(i == b);  很明显,布尔型不能和其他基本数据类型比较,编译报错.
      		System.out.println(System.identityHashCode(i));
      		System.out.println(System.identityHashCode(j));
      		System.out.println(System.identityHashCode(m));
      		System.out.println(System.identityHashCode(k));
      		System.out.println(System.identityHashCode(b));
      	}
      }
      

      输出结果:

      true
      true
      true
      *******************
      366712642
      1829164700
      2018699554
      1311053135
      118352462
      

      分析:

      ​ ①根据比较的结果和内存地址来看,内容一样,内存地址不一样,但是返回的结果都是true,说明比较的 时候只看变量中存储的内容是否相同,而跟内存地址无关。

      ​ ②==比较的两边数据需要能强制转换成同一类型,比如intdouble的比较,会强制转换到double

      ​ ③布尔类型不能和int,float,double,char等基本数据类型做比较,编译时就报错。

      2.对于引用数据类型的比较:

      public class Test{
      	
      	public static void main(String[] args) {
      		Test t1 = new Test();
      		Test t2 = new Test();
              String name1 = "琼宝";
      		String name2 = "琼宝";
      		
      		System.out.println(name1 == name2);						 // true
      		System.out.println(System.identityHashCode(name1));		 //366712642	
      		System.out.println(System.identityHashCode(name2));		 //366712642
      		
      		System.out.println(t1 == t2);                             //false
      		System.out.println(System.identityHashCode(t1));          //366712642
      		System.out.println(System.identityHashCode(t2));          //1829164700
              System.out.println(System.identityHashCode(new Test()));  //2018699554
      		System.out.println(System.identityHashCode(new Test()));  //1311053135
              System.out.println(new Test() == new Test());
      	}
      }
      
      

      输出结果:

      true
      366712642
      366712642
      false
      366712642
      1829164700
      2018699554
      1311053135
      false
      

      分析:

      ​ ①对于引用数据类型,此时涉及到两块内存的问题, 而且比较的也是内存地址是否相同,比如执行语句

      Test t1 = new Test() Test t2 = new Test()时,会开辟两块内存,一块用于储存t1 t2 ,一 块用于储存两个 new Test()。而很明显的是,t1和t2的内存地址不一样,就连两个new Test()的地 址都不一样,所以此时用==来比较的时候,结果必然是false.(补充:t1和t2中存储的其实是new Test() 对象使用的内存的首地址。)

      ​ ②对于String类型来说,内容相同的时候,其内存地址也相同,比较的时候看的也是地址。

      ​ ②如果要比较对象中存储的内容是否相同(不是比较地址),那么==就无法实现,此时需要equals.


    • equals的分析

      1.先看一个equals比较的栗子:

      public class TestEquals {
      	public static void main(String[] args) {
      		
      		TestEquals t1 = new TestEquals();
      		TestEquals t2 = new TestEquals();
      		System.out.println(t1.equals(t2));  //false
      		
      		String s1 = new String();
      		String s2 = new String();		
      	
              System.out.println(System.identityHashCode(s1));
      		System.out.println(System.identityHashCode(s2));
      		System.out.println(System.identityHashCode(new String()));
      		System.out.println(System.identityHashCode(new String()));
              System.out.println(s1.equals(s2));  // true
      	}
      }
      
      输出结果:
      false
      366712642
      1829164700
      2018699554
      1311053135
      true
      

      2.分析:

      ​ ①t1和t2的比较是false,而s1和s2的比较是true,这里就涉及到了equals方法的重写问题,先看 Object类 中equals的源码:

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

      ​ ② 对于s1.equals(s2) ,this就是s1,obj是s2,而源码中的比较用的是==,很明显是引用数据类型的比 较,看的是s1和s2的内存地址,上面的分析已经知道他们的地址不一样,所以结果自然就是false.

      ​ ③而s1和s2的比较结果是true,这是因为在String类中,equals方法被重写了,看源码:

      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;
          }
      

      ​ ④通过和object中equals源码的对比可以看出,String中的equals方法比较的不再是对象的地址,而是看 两个对象内容,或者两个对象的属性是否都一样。

      ​ ⑤像String,Date,File…等类都对equals方法进行了重写。


    • 总结

      1.==用于比较基本数据类型时,比较的是内容是否相等,比较引用数据类型时,看的是内存地址是否相等。

      2.equals只能比较引用数据类型(对象),没被重写之前,使用==来比较内存地址,重写后比较的是对象的具 体内容和属性是否一致。

      3.创作不易。感谢支持,欢迎转载转发,但请注明出处。

      4.如对你有帮助,老板大气,感谢打赏一杯熬夜咖啡。

      5 .QQ 321662487

    在这里插入图片描述在这里插入图片描述

  • 相关阅读:
    FlashSocke 通过flash进行socket通信(as代码)
    JavaScript 中的对象深度复制(Object Deep Clone)
    map,vector 等容器内容的循环删除问题(C++)
    [转]用JavaScript在浏览器中创建下载文件
    [记]WIndow/Linux 获取本机(全部)IPv4、IPv6、MAC地址方法 (C/C++)
    [记]Debian alias 设置, 不设置貌似有点不方便习惯
    Linux 安装配置 FTP 服务 (vsftpd)
    FreeSWITCH 安装配置的 各种坑, 填坑
    ubuntu编译安装ruby1.9.3,从p551降级到p484
    redmine3.3.3 rake db:migrate 报错invalid byte sequence in US-ASCII (Argument Error) 解决方法
  • 原文地址:https://www.cnblogs.com/coding-996/p/12000245.html
Copyright © 2020-2023  润新知