简单的一句话说明就是:

== 比较Stack中的值(引用数据类型stack中存放的是对象的堆内存地址)。

equals() 通常被覆写为比较对象的值

那么==和equals()之间到底有什么具体的区别呢?

如果单从Object类或继承于Object没有做出任何覆写操作的类来看,==和equals()之间没有任何区别,equals方法由Object类提供,在Object中对equals的实现是这样的:

public boolean equals(Object o){

return this == o;

}

但事实是API中的大部分类为我们重写了equals方法,例如String中,equals方法就被覆写为了对值的比较,String中的equals是这样操作的:

  1. 判断传入方法的字符串与当前字符串长度是否一致,如果不一致则没有必要再进 行比较了,直接返回false
  2. 如果长度一致则把两个支付串转换成char数组,通过循环对两个数组中的同位元素进行比较,其中有任意一对同位元素不一致则中断循环,返回false
  3. 如果循环完成任然没有跳出循环,则在循环自然中断后返回true

由此可见,在String中的equals实际是在对字符串的每一个值进行比较

但有时候==确让我们在比较值的错觉,如下列情况:

String a="Test";

String b="Test";

if(a= =b) ===> true

结果确实是我们想要得到的true,似乎比较成功了,但是!

这是因为当你创建任何字符串文字时,JVM首先在字符串池中搜索该文字,并且如果找到匹配项,那么同样的引用将被赋予新的String。因此,我们得到了

(a = = b)===> true

简而言之就是a和b指向了相同的堆内存区

String Pool

b -----------------> "test" <-----------------a

但是,==在以下情况下失败。

String a="test";

String b=new String("test");

if (a==b) ===> false

在这种情况下,new String("test")对于新的String将在堆内存区中创建新的引用赋予给b,此时b所指向的内存地址与a指向不同
if(a == b)===> false。

String Pool

"test" <-------------------- a

Heap

"test" <-------------------- b

那在Integer等包装类型又会如何呢:

我们不妨来看看下面这个实验

Integer i_1 = 1;

Integer i_2 = 1;

Integer i_3 = new Integer(1);

System.out.println(i_1.equals(i_2)); //true

System.out.println(i_1.equals(i_3)); //true

System.out.println(i_1 == i_2); //true

System.out.println(i_1 == i_3); //false

好了,看上去一切真相大白,这个结果和我们期望的一模一样,真是这样吗?我们把i_1和i_2的值进行一个修改看看

Integer i_1 = 128;

Integer i_2 = 128;

System.out.println(i_1 == i_2);

这个结果出人意料的返回了false,这是什么原因?看看Integer的equals方法实现过程

public boolean equals(Object obj) {

if (obj instanceof Integer) {

return value == ((Integer)obj).intValue();

}

return false;

}

这个方法告诉我们,Integer其实还是在用==做对象的比较,其中的value是一个int类型,在Integer中定义value是这样的

private final int value;

这个方法毫无争议,它和String中的equals有相同的思想。

我们在看看Integer i_1 = 1这段代码,其实Integer i_1 = 1的这种操作形式是调用Integer的valueOf方法,而valueOf方法在Integer中的声明如下:

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high){

return IntegerCache.cache[i + (-IntegerCache.low)];

}

return new Integer(i);

}

不难发现,在某个范围内Intger直接从IntegerCache中取值,超出了这个范围则执行new Intger,而IntegerCache的范围正好是-128~127,因此,当Integer i_1和i_2直接赋值这个范围时==返回为true,超出范围自然返回为false

所以当你不知道到底应该使用哪个方法时,使用.equals()总是更好的。

文章原创。

若转载,请注明出处:“来自蜗牛学院cto李懿老师”。

若没有按照以上注明出处,一经发现必追究。

作者:蜗牛学院CTO李懿老师

==和equals()的区别的更多相关文章

  1. Java学习笔记——双等号和equals的区别

    一.==和equals的区别 1. ==可以用来比较基本类型和引用类型,判断内容和内存地址 2. equals只能用来比较引用类型,它只判断内容.该函数存在于老祖宗类 java.lang.Object ...

  2. java中的==和equals的区别

    关于JAVA中的==和equals函数的区别 今天在研读Thinking in java 时注意到==和equals的区别,于是就通过查看JDK_API才读懂了他们的区别,于是将心得分享一下,望批评指 ...

  3. android错误之==与equals的区别

    在做一个电话号码匹配的时候, 开始我使用的是这种情况 if (num == inCall.getNum()) { //操作... } 但是无论如何结果都是false,就算两个号码打印出来一模一样还是f ...

  4. Java基础系列之你真的懂==与equals的区别吗?

    对于Java初学者而言,可能会对这两个比较方法比较模糊,有的人可能会觉得两个的方法使用起来结果是一样的等.如果你有这样的想法,我建议你来看看这边博客,让你充分了解这两个比较的异同,以及他们底层是如何比 ...

  5. Java 中 == 和 equals 的区别

    有一段时间,== 和 equals 的区别一直困扰着我.因为涉及到Java的内存机制,然而Java的内存机制又是比较抽象的东西,所以对那时候的我来说,实在是很难理解. == 和 equals 最大的区 ...

  6. java 的==和equals的区别(二)

    java 的==和equals的区别 java 的==和equals的区别 ==通常表明引用的是同一个东西(引用的地址相同),equals通常表明两个对象的内容相同(值相同) ------------ ...

  7. equals与==区别

    equals与==区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean   他们之间 ...

  8. “==”与equals的区别

    “==”与equals的区别: “==”:两个对象比较的是对象的引用地址比较,对象的hashCode值是对象的引用地址,只有两个对象的hashCode值一样,此比较符才会返回true,否则即使两个对象 ...

  9. 浅谈==和equals的区别

    java中的==和equals的区别? 看上面的代码,输出的结果是: true false true true 1.为什么会有上面的区别呢?==和equals比较的到底是什么呢? 搞清楚两者的区别其实 ...

  10. Java中Object.equals和String.equals的区别详解

    前言 Java中的堆和常量池的区别是什么呢?Object.equals与String.equals的区别呢?下面让我们通过一个小示例让你明白它- 1.基础知识 Java的存储空间:寄存器.栈.堆.静态 ...

随机推荐

  1. Pandas数据处理实战:福布斯全球上市企业排行榜数据整理

    手头现在有一份福布斯2016年全球上市企业2000强排行榜的数据,但原始数据并不规范,需要处理后才能进一步使用. 本文通过实例操作来介绍用pandas进行数据整理. 照例先说下我的运行环境,如下: w ...

  2. HDU 1814 Peaceful Commission / HIT 1917 Peaceful Commission /CJOJ 1288 和平委员会(2-sat模板题)

    HDU 1814 Peaceful Commission / HIT 1917 Peaceful Commission /CJOJ 1288 和平委员会(2-sat模板题) Description T ...

  3. javascript事件轮询

    JavaScript 运行机制详解:再谈Event Loop 一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么Ja ...

  4. 记一次 联想杨天A4600K 安装操作系统遇到的尴尬

    故事的开始: 某日,有一台联想扬天A4600K台式机,该机器原来使用的系统为windowsXP,先需要安装win7系统. 准备好gho镜像,准备ghost安装系统.不料,提示镜像文件损坏,无法安装.起 ...

  5. 实施软件测试风险分析&回归用例刷选

    [一两年前收集整理的资料,感觉不错,放到博客上来] 作为软件测试计划的一部分,软件测试风险的分析与控制是其中重要的环节.如果前期风险分析与控制比较充分,那么会使软件的测试成功性大大增加,且可将由风险异 ...

  6. ajax-post请求

    一般来说字符串读取不出来查看下面这行代码是否加上: xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencode ...

  7. oracle高级查询(实例基于scott用户四张表)

    oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ====================================================== ...

  8. 【CSS】整屏大背景

    1. 利用div的层次,设置底层div充满屏幕,并给div设置背景图 <div id="Layer1" style="position:absolute;top:0 ...

  9. vue组件的那些事($children,$refs,$parent)的使用

    如果项目很大,组件很多,怎么样才能准确的.快速的寻找到我们想要的组件了?? 1)$refs 首先你的给子组件做标记.demo :<firstchild ref="one"&g ...

  10. Hive笔记——技术点汇总

    目录 · 概况 · 手工安装 · 引言 · 创建HDFS目录 · 创建元数据库 · 配置文件 · 测试 · 原理 · 架构 · 与关系型数据库对比 · API · WordCount · 命令 · 数 ...