• 关于java中equals与==的区别的小实验


    java中equals与==经常容易混淆,简单一点说就是equals比较的是值是否相等,是一种方法,==比较的两个对象在JVM中的地址,是一种操作符。

    做了几个小实验比较结果。

    实验一:

    String str1="ab";
    String str2="ab";
    System.out.println(s1==s2);//true
    System.out.println(str1.equals(str2));//true

    这里的str1与str2都指向了常量池中的同一对象,所以System.out.println(s1==s2);返回为true,当然,str1与str2二者字符串的值也是相同的。

    实验二:

    1 String str1="ab";
    2 String str2="abc";
    3 System.out.println(str1==str2);//false
    4 System.out.println(str1.equals(str2));//false

    这里的str1指向了字符串ab,初始时在常量池中并没有找到字符串abc,则开辟地址存储字符串abc,并将str2指向了abc字符串,所以str1与str2与并不是一个对象,他们的字符串值也不相同。

    实验三:

    1 String str1="ab";
    2 String str2="ab";
    3 String str6=str2;
    4 System.out.println(str1==str6);//true
    5 System.out.println(str2==str6);//true
    6 System.out.println(str1.equals(str6));//true
    7 System.out.println(str2.equals(str6));//true

    这里将str2的值赋值给str6,因为常量池中已经存在了ab这个字符串,所以str1、str2与str6共享了同样的对象,==与equals同样返回true

    实验四:

    1 String str1= new String("abc");
    2 String str2= "abc"3 System.out.println(str1==str2);//false

    创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。
    以上代码说明,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。

    实验五:

    1 String str1="ab";
    2 String str3=new String("ab");
    3 String str4=new String("ab");
    4 System.out.println(str3==str4);//false
    5 System.out.println(str1.equals(str3));//true
    6 System.out.println(str3.equals(str4));//true

    因为str3与str4的字符串的值是相同的,所以str3.equals(str4)为true,但是由于str3与str4指向的不是同一个对象,所以str3==str4返回是false。同样因为str1与str3字符串的值是相同的,尽管str1与str3指向的不是同一个对象,str1.equals(str3)同样返回的是true

    实验六:

     1 String str1="ab";
     2 String str3=new String("ab");
     3 String str4=new String("ab");
    String str5=str3;
    4 System.out.println(str1.equals(str3));//true 5 System.out.println(str3.equals(str4));//true 6 System.out.println(str3.equals(str5));//true 7 System.out.println(str4.equals(str5));//true 8 System.out.println(str3==str5);//true 9 System.out.println(str4==str5);//false 10 System.out.println(str1==str5);//false 11 System.out.println(str1.equals(str5));//true

    这里将str3赋值给str5,所以str3与str5指向了同一对象,这样str3==str5返回为true值,str3.equals(str5)同样返回true值。由于str4与str5指向的不是同一对象,所以str4==str5返回false。但是也是因为字符串的值是相同的,所以str4.euqals(str5)返回为true值。

    下面是以上实验所有的代码:

     1 public class Test 
     2 {
     3     public static void main(String[] args) 
     4     {
     5         String str1="ab";
     6         String str2="abc";
     7         String str6=str2;
     8         String str3=new String("ab");
     9         String str4=new String("ab");
    10                 String str5=str3;
    11         System.out.println(str1==str6);//true
    12         System.out.println(str2==str6);//true
    13         System.out.println(str1.equals(str6));//true
    14         System.out.println(str2.equals(str6));//true
    15         System.out.println(str1==str2);//true
    16         System.out.println(str1.equals(str2));//true
    17         System.out.println(str3==str4);//false
    18         System.out.println(str1.equals(str3));//true
    19         System.out.println(str3.equals(str4));//true
    20         System.out.println(str3.equals(str5));//true
    21         System.out.println(str4.equals(str5));//true
    22         System.out.println(str3==str5);//true
    23         System.out.println(str4==str5);//false
    24         System.out.println(str1==str5);//false
    25             System.out.println(str1.equals(str5));//true
    26     }
    27 }

     将String类换成Integer包装类,测试代码及结果如下:

     1 class TestNumber
     2 {
     3     public static void main(String[] args) 
     4     {
     5         Integer str1=23;
     6         Integer str2=23;
     7         Integer str6=str2;
     8         Integer str3=new Integer(23);
     9         Integer str4=new Integer(23);
    10         Integer str5=str3;
    11         System.out.println(str1==str6);//true
    12         System.out.println(str2==str6);//true
    13         System.out.println(str1.equals(str6));//true
    14         System.out.println(str2.equals(str6));//true
    15         System.out.println(str1==str2);//true
    16         System.out.println(str1.equals(str2));//true
    17         System.out.println(str3==str4);//false
    18         System.out.println(str1.equals(str3));//true
    19         System.out.println(str3.equals(str4));//true
    20         System.out.println(str3.equals(str5));//true
    21         System.out.println(str4.equals(str5));//true
    22         System.out.println(str3==str5);//true
    23         System.out.println(str4==str5);//false
    24     }
    25 }

     补充说明:

    Integer类的equals源码

    1  public boolean equals(Object obj) {  
    2     if (obj instanceof Integer) {  
    3         return value == ((Integer)obj).intValue();  
    4     }  
    5     return false;  
    6     }  

    可见,Integer中的equals中的是直接取得数值进行比较

    而String中的equals源码如下:

     1 public boolean equals(Object anObject) {
     2         if (this == anObject) {
     3             return true;
     4         }
     5         if (anObject instanceof String) {
     6             String anotherString = (String) anObject;
     7             int n = value.length;
     8             if (n == anotherString.value.length) {
     9                 char v1[] = value;
    10                 char v2[] = anotherString.value;
    11                 int i = 0;
    12                 while (n-- != 0) {
    13                     if (v1[i] != v2[i])
    14                             return false;
    15                     i++;
    16                 }
    17                 return true;
    18             }
    19         }
    20         return false;
    21     }

    可见,String类中的源码与Integer中的有所不同,不同之处在于先采用了==方式进行比较,如果不是同一个对象再比较值,可见这个equals函数适用于存储在常量池中的字符串,例如

    1 String str1="ab";
    2 String str2="ab";
    3 System.out.println(str1.equals(str2));

    str1与str2的比较equals方法中的

    1 if (this == anObject) {
    2            return true;
    3       }

    进行比较得出的true

    而下面的例子:

    1 String str3=new String("ab");
    2 String str4=new String("ab");
    3 System.out.println(str3.equals(str4));

    str3与str4由于不是同一对象,所以if(this==anObject)不符合条件,所以进行下面字符串值的比较,最后返回true

    下面的例子同理

    String str5="abc";
    String str6=new String("abc");
    System.out.println(str5.equals(str6));

     但这里还有一个陷阱,就是Integer类,可以参考这个类的源码,知道了Integer类缓存了-128到127,官方的解释是小的数字使用的频率比较高,超过这个范围的时候就会执行new Integer,可见如下代码

    Integer a=1000;
    Integer b=1000;
    System.out.println(a==b);//false;
    

    是正确的

    但是一旦两个变量a与b被赋值为100,结果就是true

    如下代码:

    Integer a=new Integer(1000);
    int b=1000;
    Integer c=new Integer(1000);
    Integer d=new Integer(1000);
    System.out.println(a==b);//true
    System.out.println(c==d);//false 

    由于c与d是new Integer得到的结果,并没有使用缓存,所以c与d并不是同一个对象,输出的结果是false

    但是a与b为什么是true呢?

    因为Integer与int进行==比较的时候,java会把Integer自动拆箱,转为int类型,这样就a与b就指向了同一对象,所以会输出true

  • 相关阅读:
    继承作业0920
    类与对象
    类和对象基础题
    类和对象数组
    数组
    字符串
    2.1面向对象
    7.1 Java集合概述
    Java动态代理的两种实现方法
    18.5.2动态代理和AOP
  • 原文地址:https://www.cnblogs.com/yangxiaoguai132/p/5035316.html
Copyright © 2020-2023  润新知