之前有在 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. restful 与 webapi 详解

    restful 什么是API API全称Aplication Programming Itererface即应用程序编程接口, 我们在开发应用程序时经常用到.API作为接口,用来"连接&qu ...

  2. CLS的探索:Python如何让日志免费云化

    前言 日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集.日志存储到日志检索,图表分析.监控告警.日志投递等多项服务,协助用户通过日志来解决业务运 ...

  3. blazor发布之后 刷新404的解决方法

    其实所有单页面应用都一样 只需要在nginx里面配置 location / { root html; index index.html index.htm; rewrite ^/.*/$ / last ...

  4. 企业是否可以用CRM做邮件营销?

    最近总有一些从事外贸,跨境电商的朋友问小Z:"我的企业能用CRM做邮件营销吗?" 我回答:"能,Zoho CRM系统不但能用来发营销邮件,还发得聪明.发得到位." ...

  5. pytorch实现LeNet5分类CIFAR10

    关于LeNet-5 LeNet5的Pytorch实现在网络上已经有很多了,这里记录一下自己的实现方法. LeNet-5出自于Gradient-Based Learning Applied to Doc ...

  6. vscode 取消 eslint everywhere

    vscode装了eslint插件,一不小心点了eslint everywhere 然后任务栏就变成这样了 eslint前面是双钩 不管你打开什么项目,什么工作空间,永远都是默认开启ESlint!!! ...

  7. [Python] tkinter 之 Listbox & Combobox

    示例: 1 #用户界面 2 import os 3 os.chdir('F:\\spyder_workspace\\ColCal') 4 import Main 5 from tkinter impo ...

  8. 消息队列之 RabbitMQ【验证通过】

    消息队列之 RabbitMQ 预流 关注  22.9 2017.05.06 16:03* 字数 4884 阅读 284691评论 41喜欢 618赞赏 2 关于消息队列,从前年开始断断续续看了些资料, ...

  9. Scala 字符串插值器

    Scala 提供了三种创新的字符串插值方法:s,f和raw,使用他们我们可以方便快捷的组合字符串. s 字符串插值器 在任何字符串前加上s,就可以直接在串中使用变量了,在生成字符串的时候会隐式调用其t ...

  10. mysql基础之帮助信息

    在mysql中获取帮助 1.当连接到mysql数据库以后,使用help命令或者\?表示获取帮助信息: MariaDB [ren]> help General information about ...