Java之equals和==的区别

1. 基础数据类型
    Java中的基础数据类型 byte,short,char,int,long,float,double,boolean,使用==进行值的比较,没有equals方法。

2. 复合数据类型
    Java中不是基础数据类型的其他类型都是复合数据类型,包括:class、interface、数组、String。所有类都是从Object中衍生而来,在Object类中定义的equals方法源码为:
    public boolean equals(Object obj) {
         return (this == obj);
    }
    可见,未覆盖的equals方法是由==实现的,而对于复合数据类型,== 比较的是两个对象的内存地址,除非两个对象指向的是同一个内存地址的引用,才可能相同。调用未重写的equals方法是没意义的,其结果与==的结果一致。
    例如:
    class Words {
 String value;
 Words(String str) {
  value = str;
 }
    }
    
  Words s6 = new Words("abcde");
  Words s7 = new Words("abcde");
  Words s8 = s7;
  System.out.println("s7 equals s6: " + s7.equals(s6));
  System.out.println("s7 == s6: " + (s7 == s6 ));
  System.out.println("s8 equals s7: " + s8.equals(s7));
  System.out.println("s8 == s7: " + (s8 == s7 ));
 输出结果为:
    s7 equals s6: false
    s7 == s6: false
    s8 equals s7: true
    s8 == s7: true

    我们可以重写equals方法,例如在String类中重写的equals方法源码为:
    public boolean equals(Object anObject) {
 if (this == anObject) {
     return true;
 }
 if (anObject instanceof String) {
     String anotherString = (String)anObject;
     int n = count;
     if (n == anotherString.count) {
  char v1[] = value;
  char v2[] = anotherString.value;
  int i = offset;
  int j = anotherString.offset;
  while (n-- != 0) {
      if (v1[i++] != v2[j++])
   return false;
  }
  return true;
     }
 }
 return false;
    }
    可见,equals先比较两个对象的内存地址,若指向同一个内存地址,则返回true;
    若内存地址不同,equals再比较的是两个String对象的内容,即长度与每个字符的值,相同则返回true。
所以:
    String s4 = new String("abcde");
    String s5 = new String("abcde");
    String s9 = s5;
    System.out.println("s5 equals s4: " + s5.equals(s4));
    System.out.println("s5 == s4: " + (s5 == s4 ));
    System.out.println("s5 equals s9: " + s5.equals(s9));
    System.out.println("s5 == s9: " + (s5 == s9 ));
输出结果为:
    s5 equals s4: true
    s5 == s4: false
    s5 equals s9: true
    s5 == s9: true

    我们知道String的equals方法进行了重写的,但是,对于下面的代码:
    String s1 = "abc";
     String s2 = "abc";
    System.out.println("s1 equals s2:" + s1.equals(s2));
    System.out.println("s1 == s2: " + (s1 == s2));
    输出结果为:
    s1 equals s2:true
    s1 == s2: true
   可以看出,s1==s2的结果与上面s4==s5的结果不同。原因在于,创建s4,s5时使用的是new,会在内存中各开辟一块空间存放s4,s5对象,所以二者的内存地址不同,s5 == s4的结果为 false;而创建s1,s2时,二者引用的是同一个String对象,所以 s1 == s2的结果为true。
    类似地,如果:
    String s3 = "abcde";
    String s4 = new String("abcde");
    System.out.println("s3 equals s4: " + (s3.equals(s4)));
    System.out.println("s3 == s4: " + (s3 == s4 ));
    输出结果为:
s3 equals s4: true 
s3 == s4: false
    如果交换s3,s4的位置:
  String s4 = new String("abcde");
String s3 = "abcde";
   输出的结果仍为:
s3 equals s4: true 
s3 == s4: false
因为使用new一定是创建一个新对象s4,此时,不管Constant Pool中是否已经有相同值的对象存在,都会创建一个新的String对象存储在堆中,然后返回其引用给s3。
Constant Pool是Java编译好的class文件中的一个区域,是一个由数组组成的表,用来存储程序中使用的各种常量,包括Class、String、Integer等类型。



总结:
     当用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 Java当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是使用(==)比较对象的内存地址,比较后的结果跟双等号(==)的结果相同。但在一些类当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,可能不再是比较类在内存中的存放地址了。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值