之前有在 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. Spring MVC工作原理及源码解析(二)DispatcherServlet实现原理及源码解析

    1.DispatcherServlet 处理流程 从上一篇文章中Spring MVC原理图中我们可以看出:DispatcherServlet 在 Spring MVC框架 中处于核心位置,它负责协调和 ...

  2. 【Docker】7. 镜像-加载原理、分层原理、commit镜像

    一.什么是镜像 镜像是一种轻量级.可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件. 它包含运行某个软件所需的所有内容,包括代码.运行时环境.库.环境变量和配置文件. 所有的应用,直接 ...

  3. 『动善时』JMeter基础 — 14、使用JMeter发送Post请求

    目录 1.Post请求参数类型说明 2.用于演示的项目说明 3.发送Post请求示例 (1)测试计划内包含的元件 (2)请求参数类型为x-www-form-urlencoded 4.请求参数form- ...

  4. Zabbix 常用术语

    Zabbix 常用术语 1.主机(host) 一台你想监控的网络设备,用IP或域名表示 2.主机组(host group) 主机的逻辑组;它包含主机和模板.-个主机组里的主机和模板之间并没有任何直接的 ...

  5. LDAP协议入门

    LDAP协议入门(轻型目录访问协议) LDAP简介 轻型目录访问协议,全称:Lightweight Directory Access Protocol,缩写:LDAP,它是基于X.500标准的,但是简 ...

  6. IT菜鸟之OSI七层模型

    OSI七层模型从下到上分别是: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 第一层物理层: 物理层是传输媒介(网线.无线.光纤) 在线路中起到的作用:是将0/1转换成电信号或光信号 物 ...

  7. 常用数据库连接池配置及使用(Day_11)

    世上没有从天而降的英雄,只有挺身而出的凡人. --致敬,那些在疫情中为我们挺身而出的人. 运行环境 JDK8 + IntelliJ IDEA 2018.3  优点: 使用连接池的最主要的优点是性能.创 ...

  8. APP测试(appium+Python基础操作)一

    一.Appium入门案例 demo from appium import webdriver from time import sleep # server 启用参数 desired_caps = { ...

  9. 启动dubbo消费端过程提示No provider available for the service的问题定位与解决

    文/朱季谦 某次在启动dubbo消费端时,发现无法从zookeeper注册中心获取到所依赖的消费者API,启动日志一直出现这样的异常提示 Failed to check the status of t ...

  10. ThinkPHP无限级分类(递归)

    代码演示 没什么可说的直接看代码 <?php namespace app\controller; class Category { //模拟假数据 protected static functi ...