之前有在 Java字符串比较(3种方法)以及对比 C++ 时的注意项 中写过一点关于 equals()与==的比较,但最近的Java考试复习过程中发现有部分情况没涉及到,故重新学习一下


在编写代码的时候我们经常会使用 equals== 来判断两个对象是否相等,那么两者有什么区别呢,主要有以下几点区别:

  1. 首先的区别是,equals 是方法,而 == 是操作符;

  2. 对于基本类型的变量来说(如 shortintlongfloatdouble),只能使用 == ,因为这些基本类型的变量没有 equals 方法。对于基本类型变量的比较,使用 == 比较, 一般比较的是它们的值

  3. 对于引用类型的变量来说(例如 String 类)才有 equals 方法,因为 String 继承了 Object 类, equals 是 Object 类的通用方法。对于该类型对象的比较,默认情况下,也就是没有复写 Object 类的 equals 方法,使用 == 和 equals 比较是一样效果的,都是比较的是它们在内存中的存放地址。但是对于某些类来说,为了满足自身业务需求,可能存在 equals 方法被复写的情况,这时使用 equals 方法比较需要看具体的情况,例如 String 类,使用 equals 方法会比较它们的值

对于上述第三点理解起来可能有点复杂,因为这里 equals 方法比较需要分两种情况来讨论,一种情况是该方法没有被重写,另外一种是该方法被重写。

  • 对于 equals 方法没有被重写的情况。如果类没有重写该方法,那么默认使用的就是 Object 类的方法,以下是 Object 类的 equals 方法:

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

从源码可以看出,里面使用的就是 == 比较,所以这种情况下比较的就是它们在内存中的存放地址。

  • 对于 equals 方法被重写的情况。以 String 类为例,以下是 String 类中的 equals 方法:

      @Override public boolean equals(Object other) {
    if (other == this) {
    return true;
    }
    if (other instanceof String) {
    String s = (String)other;
    int count = this.count;
    if (s.count != count) {
    return false;
    }
    if (hashCode() != s.hashCode()) {
    return false;
    }
    char[] value1 = value;
    int offset1 = offset;
    char[] value2 = s.value;
    int offset2 = s.offset;
    for (int end = offset1 + count; offset1 < end; ) {
    if (value1[offset1] != value2[offset2]) {
    return false;
    }
    offset1++;
    offset2++;
    }
    return true;
    } else {
    return false;
    }
    }

从源码可以看出, String 类复写了 equals 方法,当使用 == 比较内存的存放地址不相等时,接下来会比较字符串的内容是否 相等,所以 String 类中的 equals 方法会比较两者的字符串内容是否一样。我们来看看下面的例子:

    String a = "Hello World";
String b = new String("Hello World");
String c = b; //引用传递
System.out.println("a == b:" + a == b); //false
System.out.println("b == c:" + b == c); //true
System.out.println("a == c:" + a == c); //false
System.out.println("a.equals(b):" + a.equals(b)); //true
System.out.println("b.equals(c):" + b.equals(c)); //true
System.out.println("a.equals(c):" + a.equals(c)); //true 最终的打印会是:
a == b:false
b == c:true
a == c:false
a.equals(b):true
b.equals(c):true
a.equals(c):true

因为 String b 通过 new 的方式已经开辟了新的堆内存,而 String a = "Hello World" 是存放在常量池里的,两者在 Java 内存里存在放的位置是不同的,所以 a == b 为 false;而 equals 方法当两者存放的内存地址不同时,会比较两者的值,两者的值都是 "Hello World" ,所以 a.equals(b) 为 true。


另外请思考一下下方代码的运行结果为什么是 True、false

public class Java_epuals {
public static void main(String[] args) {
Integer i2 = 10;
Integer i3 = 10;
System.out.println(i2 == i3); // true Integer i4 = 128;
Integer i5 = 128;
System.out.println(i4 == i5); // false
}
}

对于 i2i3 的比较,因为变量的定义方法是 i2(i3) = 10 它们的变量会置于常量区,两个变量的内存地址相同。

此时 == 返回 true

那么为什么 i4i5 是返回 false 呢?

这是因为 Java 中 integer 范围取值要在-128到+127 (为什么Integer对象范围(-128-127)之间),而我们赋的值是 128 ,此时变量并不在常量区定义。所以两个变量的内存地址不同,== 返回 false

【Java】equals 和 == 的区别的更多相关文章

  1. java equals和==的区别

    大概说equals和==都比较的是什么: 1. boolean tem = a == b; 首先==比较的肯定是地址,从堆栈的角度说也就是说==比较的是栈上面的内容.因为栈是用来存放地址或是java中 ...

  2. java equals 和 == 的区别

    )1. == 可以用来比较基本类型以及引用类型.在基本类型中 == 比较的是两个变量的值是否相等.在引用类型中,== 比较的是两个对象的内存地址是否相等. )2. equals 只能用来比较引用类型. ...

  3. Java笔记——equals和==的区别

    摔在这里几次,还是记下来吧. 原文:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html -------------- ...

  4. java中equals和==的区别 (转)

    java中equals和==的区别  值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引 ...

  5. 【转】Java中equals和==的区别

    [转]Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boole ...

  6. java笔记---equals和==的区别

    摔在这里几次,还是记下来吧.原文:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452156.html --------------- ...

  7. java equals和==区别及string类的说明

    一.equals和==的区别 1.1.equals之string字符串的比较 1.1.1.源码如下图 if (this == anObject) {            return true;  ...

  8. Java 中 Equals和==的区别(转)

    另外一篇参考: https://blog.csdn.net/striverli/article/details/52997927 在谈论equals和==的区别前,我们先简单介绍一下JVM中内存分配的 ...

  9. Java中equals和==的区别?为什么重写equals方法后,一定要重写hashCode方法?

    首先明确一点,equals是方法,==是操作符. 1. 如果比较的是基本数据类型: 只讨论==,因为equals是不存在的,因为java中基本数据类型不能调用method的. 2. 如果比较的是引用类 ...

  10. equals和==的区别 (Java基础)

    1. == 是一个运算符.2.Equals则是string对象的方法,可以.(点)出来. 我们比较无非就是这两种 1.基本数据类型比较 2.引用对象比较 1.基本数据类型比较 ==和Equals都比较 ...

随机推荐

  1. CRM系统全方位管理企业

    您在选择一款CRM系统的时候,首先要考虑销售团队的感受和意见.让CRM系统在帮助销售团队优化工作流程的同时,更好地对销售团队进行管理.销售人员每卖出一件商品,要从寻找筛选商机开始,经过沟通客户需求.满 ...

  2. java集合类介绍

    目录 集合类简介 List ArrayList LinkedList Vector Stack Set HashSet LinkedHashSet TreeSet Map HashMap Hashta ...

  3. [转载]XStar's Libvirt+KVM部署记录 目录

    XStar's Libvirt+KVM部署记录 目录 Create: 2013-12-11 Update: 2014-01-03 准备工作 KVM网站 http://sourceforge.net/p ...

  4. 使用autotools工具用configure、make、make install编译安装linux工程的详细步骤

    使用autotools工具用configure.make.make install编译安装linux工程的详细步骤 转载tmxkwzy 最后发布于2016-11-24 10:20:15 阅读数 324 ...

  5. 【IBM】netperf 与网络性能测量

    netperf 与网络性能测量 汤凯2004 年 7 月 01 日发布 WeiboGoogle+用电子邮件发送本页面 2 在构建或管理一个网络系统时,我们更多的是关心网络的可用性,即网络是否连通,而对 ...

  6. 串口配合DMA接收不定长数据(空闲中断+DMA接收)-(转载)

    1.空闲中断和别的接收完成(一个字节)中断,发送完成(发送寄存器控)中断的一样是串口中断: 2.空闲中断是接收到一个数据以后,接收停顿超过一字节时间  认为桢收完,总线空闲中断是在检测到在接收数据后, ...

  7. MyBatis 全局配置文件详解(七)

    MyBatis 配置文件作用 MyBatis配置文件包含影响 MyBatis 框架正常使用的功能设置和属性信息.它的作用好比手机里的设置图标,点击这个图标就可以帮助我们查看手机的属性信息和设置功能.其 ...

  8. Linux shell用sed批量更改文件名的相关内容

    示例 去除特定字符 目标:将指定目录下文件名中sprint替换为dev 方法: [root@Skip-ftp test]# for i in `ls` > do > name=`echo ...

  9. Java中生成唯一标识符的方法(Day_48)

    有时候业务需要生成唯一标识符,但又不能依赖于数据库中自动递增的字段产生唯一ID,比如多表同一字段需要统一一个唯一ID,此时我们就需要用程序来生成一个唯一的全局ID. UUID UUID是指在一台机器上 ...

  10. 西门子 S7-300 以太网模块连接 WINCC方案

    北京华科远创科技有限研发的远创智控ETH-YC模块,型号有MPI-ETH-YC01和PPI-ETH-YC01,适用于西门子S7-200/S7-300/S7-400.SMART S7-200.西门子数控 ...