Java中关于Integer, String 类型变量 == 与 equals 判断的坑
== 与 equals()的联系:
==:
我们都知道Java中 == 对用于基础数据类型(byte, short, int, long, float, double, boolean, char)判断时, 是直接对变量值的比较. 而对于引用类型变量则是对变量地址的比较.
equals():
我们可以通过查阅源码看到Object类中equals()方法依然是直接对地址的比较

当然, 常见的Java类都重写了equals方法, 如封装类, Date等. 这里我们只说下Integer和String重写后的equals().
Integer的equals()是利用自动拆箱为int类型数据, 然后进行int值的比较:

而String则是逐个字符的进行比较:

上面所说的也许都知道, 之所以说一遍, 一是为了有些知道但不是很明白的同学. 二是自己再重新总结一次.
然后真正对于Integer 和 String变量 做比较时, 其实还有两个大坑
不多废话, 先上测试代码

看到运行结果是不是蒙了.
按照上面说的, 引用类型变量进行 == 比较时, 比较的是地址, 这样的话 i1 == i2结果为false我们可以理解. 但是i3 == i4 结果为true似乎解释不通.
实际上,对于-128 - 127之间的值, Integer对象从IntegerCache.cache中产生, 此范围内相同值的变量复用cache中对象, 所以指向的地址是相同的.因此i3 == i4 结果为true.

是不是更加懵逼了.
原理与Integer类似, 每个不同值的String类型变量其实是一个"常量". 单独的存储在一个特殊区域, 称为字符串常量池.
每个值不同的String变量在字符串常量池中都是唯一存在的.
举个栗子说明:
String s1 = "1";
String s2 = "1";
String s3 = "12";
System.out.println(s1 == s2);//true
System.out.println(s2 == s3);//false
只是如此简单吗? 显然不可能.
来一个测试题: 可以自己思考下再看分析
String s1 = "123";
String s2 = "456";
String s3 = "123456";
String s4 = s1 + s2;
System.out.println(s3 == s4);
System.out.println(s3.equals(s4));
结果顺序是:false, true.
是不是又有疑惑了,刚刚还说String变量值相同时, 指向常量池中同一个地址.怎么就false了呢?
其实对于第4行代码, 其原理是下面这样的

可以看到, 原理是先创建了一个StringBuilder对象,这个对象不是存在于字符串常量池中的哦! 然后分别将s1和s2拼接, 最后s4指向这个对象地址.
这样如果要进行大量的字符串拼接的话, 会创建很多对象, 造成资源浪费, 所以涉及到大量字符串拼接时建议使用StringBuffer(线程安全)或StringBuilder(非线程安全)来操作.
如果已经晕头转向了的话, 不防看下总结.
总结:
1. 对于引用类型变量(尤其是上面说到的两个), 做比较时, 推荐使用equals.
2. 字符串拼接时, 使用StringBuilder或StringBuffer来代替String.
3. 不要忽略基础的重要性, 无论学到什么时候, 基础都很重要.
4. 关注, 收藏.
PS:作者水平有限, 欢迎大佬指点不足.
Java中关于Integer, String 类型变量 == 与 equals 判断的坑的更多相关文章
- 【Java】Java中常用的String方法
本文转载于:java中常用的String方法 1 length()字符串的长度 String a = "Hello Word!"; System.out.println(a.len ...
- Java 中要将 String 类型转化为 int 类型
在 Java 中要将 String 类型转化为 int 类型时,需要使用 Integer 类中的 parseInt() 方法或者 valueOf() 方法进行转换. 例1: 1 2 3 4 5 6 S ...
- Java中如何将String转成Date
Java中如何将String转成Date 最近在开发Json数据反序列化为Java对象的时候发现spring mvc 和 Jackson 对Date类型对支持不是特别好,虽然在Java对象序列化为Js ...
- Java中的Integer和int
Java中的Integer是引用类型,而int是基本类型.Integer是int的包装器类型. java中的基本类型有布尔类型boolean;字符类型char;整数类型byte,int,long,sh ...
- Java中InputStream和String之间的转化
https://blog.csdn.net/lmy86263/article/details/60479350 在Java中InputStream和String之间的转化十分普遍,本文主要是总结一下转 ...
- java中如何将string 转化成long
1.Java中如何将string 转化成long long l = Long.parseLong([String]); 或 long l = Long.parseLong([String],[int ...
- JAVA中简单的for循环竟有这么多坑,你踩过吗
JAVA中简单的for循环竟有这么多坑,你踩过吗 实际的业务项目开发中,大家应该对从给定的list中剔除不满足条件的元素这个操作不陌生吧? 很多同学可以立刻想出很多种实现的方式,但你想到的这些实现方式 ...
- Java中数据类型转换&基本类型变量和对象型变量
1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型 byte,short,int,lo ...
- 转!!java中Object转String
Object转为String的几种形式 在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object.toString ...
随机推荐
- Python面试题: 判断IP地址是否合法
题目: 给出一个字符串, 判断其是否是是合法的IP(IPv4)地址 思路 将字符串按"."分割成4段得到一个列表 逐个判断列表中的字符串是否数字格式并且在0~255之间, 是在新列 ...
- chromedriver安装
chromedriver.exe下载 淘宝的镜像地址可以下载 https://npm.taobao.org/mirrors/chromedriver/ 找到自己chrome浏览器适合的chromeDr ...
- Qt自定义窗口部件
QtDesigner自定义窗口部件有两种方法:改进法(promotion)和插件法(plugin) 改进法 1.改进法之前,要先写好子类化QSpinBox后的HexspinBox.h和Hexs ...
- 【MyBatis】【SQL】没有最快,只有更快,从一千万条记录中删除八百万条仅用1分9秒
这次直接使用delete from emp where cdate<'2018-02-02',看看究竟会发生什么. Mapper里写好SQL: <?xml version="1. ...
- 数据库 | SQL查询&LIMIT的用法
body{ text-align:left; width:80%; margin:10px 100px; } 前言 select top n 形式的语句可以获取查询的前几个记录,但是 mysql没有此 ...
- 前端知识点回顾——Nodejs
Node.js 事件循环机制 setImmediate()是将事件插入到事件队列尾部,主线程和事件队列的函数执行完成之后立即执行setImmediate指定的回调函数,和setTimeout(fn,0 ...
- ZeroMQ——一个轻量级的消息通信组件 C#
ZeroMQ——一个轻量级的消息通信组件 ZeroMQ是一个轻量级的消息通信组件,尽管名字中包含了"MQ",严格上来讲ZeroMQ并不是"消息队列/消息中间件" ...
- 表单中使用<button>的注意点
本文主要记录了我调查问题的思路想法,想看结论的同学直接拖到最后吧 上周在做项目的时候,有一个需求是在页面中加一个按钮,点一下查询数据库将内容填充在表格中.这不是很简单嘛,页面加个按钮,发送ajax请求 ...
- php版本:实现过滤掉广告、色情、政治相关的敏感词
现在网络上还是很乱,尤其充斥着各种广告.色情.政治相关的内容,很明显这是不符合我们国家的法律的,所以为了一个产品能够健康长久的活下去,最好还是采用一定的策略过滤或者提醒用户不要发这种内容.不过说起来容 ...
- JAVA 基础编程练习题7 【程序 7 处理字符串】
7 [程序 7 处理字符串] 题目:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. 程序分析:利用 while 语句,条件为输入的字符不为'\n'. package cskaoya ...