Java Integer于Int 进行==双等于的内存比较时的一些问题说明
转自:
https://blog.csdn.net/xingkongdeasi/article/details/79618421
部分有所修改:
前言:
越是简单的东西,我们往往越是没有去把它明白,但我们大部分时间又常常在用,就像我们今天说的int与Integer的使用,我们程序员基本天天都在用,但是我今天没用详细弄清楚之前我也是不清楚,我们来看看这两个在用==号比较给我们带来的疑问。
先看看下面的代码,看看我们是否都会
@Test
public void testEquals() {
int int1 = 12;
int int2 = 12;
Integer integer1 = new Integer(12);
Integer integer2 = new Integer(12);
Integer integer3 = new Integer(127);
Integer a1 = 127;
Integer a2 = 127;
Integer a = 128;
Integer b = 128;
System.out.println("int1 == int2 -> " + (int1 == int2));
System.out.println("int1 == integer1 -> " + (int1 == integer1));
System.out.println("integer1 == integer2 -> " + (integer1 == integer2));
System.out.println("integer3 == a1 -> " + (integer3 == a1));
System.out.println("a1 == a2 -> " + (a1 == a2));
System.out.println("a == b -> " + (a == b));
}
答案是:
1、 int1 == int2 -> true
2、 int1 == integer1 -> true
3、 integer1 == integer2 -> false
4、 integer3 == a1 -> false
5、 a1 == a2 -> true
6、 a == b -> false
看看结果跟我们自己做的是不是都一样。
下面我们就来详细解释一下,为什么是上面的结果。(下面的序号就是对应的是上面的答案序号)
1、int1 == int2 为true,这个我就讲了,这个都知道
2、int1 == integer1,Integer是int的封装类,当Integer与int进行==比较时,Integer就会拆箱成一个int类型,所以还是相当于两个int类型进行比较,这里的Integer,不管是直接赋值,还是new创建的对象,只要跟int比较就会拆箱为int类型,所以就是相等的。
3、integer1 == integer2 -> false,这是两个都是对象类型,而且不会进行拆箱比较,所以不等
4、integer3 == a1 -> false , integer3是一个对象类型,而a1是一个常量它们存放内存的位置不一样,所以也不等,具体存在内存的位置看以看文章:点击打开链接
5、6 看起来是一模一样的为什么一个是true,一个是false,这是因为Integer作为常量时,对于-128到127之间的数,会进行缓存,也就是说int a1 = 127时,在范围之内,这个时候就存放在缓存中,当再创建a2时,java发现缓存中存在127这个数了,就直接取出来赋值给a2,所以a1 == a2的。当超过范围就是new Integer()来new一个对象了,所以a、b都是new Integer(128)出来的变量,所以它们不等。
根据以上总结:
①、无论如何,Integer与new Integer不会相等。不会经历拆箱过程,因为它们存放内存的位置不一样。(要看具体位置,可以看看这篇文章:点击打开链接)
(Arnold备注:new Integer()必然是堆内存中新增数据,Integer 是java的常亮实现类,如果是在-128到127时则存在于常量池中,如果大于127,则在堆内存中新增对象,==比较的为内存地址,所以即使
new Integer() 和直接使用Integer 定义数据,都是在堆内存中存储的数据,则对应的内存地址也不会相同,所以,new Integer 于 Integer 必然不会相等)
②、两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。
③、两个都是new出来的,则为false。(备注:除了进入常量池的对象,在实例化前会去常量池中比较是否有相同的内容,相同则返回当前常量池的内存地址,其余进入堆内存空间的对象,一律是直接开辟空间进行堆内存的存储,不会进行是否已经存在的判断)
④、int和integer(new或非new)比较,都为true,因为会把Integer自动拆箱为int,其实就是相当于两个int类型比较。(备注:两个int 的比较操作,实际就是直接进行值的比较的操作)
(Arnold备注:方法区常量池的概念此处不再赘述,此处主要说明下,java中常量池对基本类型的一些实现:)
Java中实现常量池的基本类型的包装类分别是:String,Byte,Short,Integer,Long,Character,Boolean,浮点数的包装类型则没有实现,Byte,Short,Integer,Long,Character 五中类型
也只是在对应的值小于 127和-128时才会实现常量池,超出该值的范围则直接在堆内创建内存,于上述介绍的Integer的常量池一致,而对于String的常量池则和上面所提到的其他类型的常量池基本一致,
对于直接String =“”“” 来创建的对象数据则是直接存储在常量池中,没有大小和范围的限制,而对于直接 使用 new 的方式创建的对象,则都会直接放到堆内存中,此处于其余的常量池的实现类是一致的。
可参考如下链接:https://blog.csdn.net/qiaoijun/article/details/48878039
String s = "Java" 这种声明的方式。产生的这种"常量"就会被放到常量池,常量池是JVM的一块特殊的内存空间。
使用Java常量池技术,是为了方便快捷地创建某些对象,当你需要一个对象时候,就去这个池子里面找,找不到就在池子里面创建一个。但是必须注意 如果对象是用new 创建的。那么不管是什么对像,它是不会放到池子里的,而是向堆申请新的空间存储。
java中基本类型的包装类的大部分都实现了常量池技术,这些类是Byte,Short,Integer,Long,Character,Boolean,另外两种浮点数类型的包装类则没有实现。另外Byte,Short,Integer,Long,Character这5种整型
Java Integer于Int 进行==双等于的内存比较时的一些问题说明的更多相关文章
- java Integer和int的拆箱与装箱
官网:http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html 1.赋值: a. 把int类型赋值给Integer类型:JVM会 ...
- java - Integer、int 、String相互转换总结
一下子还真记不清这三种数据类型之间的转换方法,所以做个小笔记. public class Test03 { public static void main(String[] args) { //int ...
- Java Integer 与 int 深刻理解
今天在做Object 自动转为Integer 类型之后的判断,遇到一个不理解的点,当数值超过127之后,两个数值相同的Object 对象用 == 判断的结果是false. Object a = 128 ...
- Java数据类型中String、Integer、int相互间的转换
1.Integer转换成int的方法 Integer i; int k = i.intValue(); 即Integer.intValue(); 2.int转换成Integer int i; Int ...
- 转:JAVA里面的int类型 和Integer类型,有什么不一样
JAVA里面的int类型 和Integer类型,有什么不一样 原文链接:http://blog.csdn.net/wuxinliulei/article/details/11099565 java.l ...
- Java进阶(三十四)Integer与int的种种比较你知道多少?
Java进阶(三十四)Integer与int的种种比较你知道多少? 前言 如果面试官问Integer与int的区别:估计大多数人只会说到两点:Ingeter是int的包装类,注意是一个类:int的初值 ...
- Java中的Integer和int
Java中的Integer是引用类型,而int是基本类型.Integer是int的包装器类型. java中的基本类型有布尔类型boolean;字符类型char;整数类型byte,int,long,sh ...
- Java中Integer和int的异同
public void Test1() { int a = 128; Integer b = 128; Integer c = 128; //Integer会自动拆箱成int,所以为ture Syst ...
- java --> Long和long/Integer和int
java中非一切是对象,因为还有基本数据类型. 基本数据类型有对应的基本数据类型打包器,它们的基本数据类型打包器是对象. j2se 5.0引入装箱和拆箱,它们是基本数据类型和基本数据类型打包器的关系 ...
随机推荐
- jQuery学习笔记(四)
动画效果 显示和隐藏效果 无动画效果 显示:show() 隐藏:hide() <!DOCTYPE html> <html lang="en"> <he ...
- 【收藏】这么多WEB组件(CSS),攒一个网站够了吧?
简言 总是喜欢简单又精致的东西,美的不繁复也不张扬.这是闷骚程序员的癖好么?闲来无事,把收集到的部分WEB组件整理汇总一下,攒一个逼格高一点的网站够了吧? 1 表单(form)相关 1.1 输入框(i ...
- mybatis 异常处理:Invalid bound statement (not found)
mybatis 的使用过程中提示错误: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): ...
- linux 命令——55 traceroute(转)
通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一 ...
- IDEA 编辑器如何将tabs 分行显示
https://jingyan.baidu.com/article/49ad8bcebd9e7c5834d8faac.html
- Python实现屏蔽敏感词
一.需求 1. 有一个文件,里面有一些敏感词汇,用户输入一段话,若包含这些词,就用**代替,并输出 二.实现代码 f = open('lib.txt', 'r') result = '' f1 = i ...
- Struts2 In Action笔记_页面到动作的数据流入和流出
因为回答百度知道的一个问题,仔细查看了<Struts2 In Action>,深入细致的看了 “数据转移OGNL 和 构建视图-标签”,很多东西才恍然大悟. 一直觉得国外写的书很浮,不具有 ...
- Linux环境下使用xampp配置php开发环境
XAMPP (Apache+MySQL+PHP+PERL)是一个功能强大的建站集成软件包.这个软件包原来的名字是LAMPP,但是为 了避免误 解,最新的几个版本就改名为 XAMPP 了.它可以在Win ...
- package.json字段分析
分析1.必须在包的顶层目录下2.二进制文件应该在bin目录下3.javascipt在lib目录下4.文档在doc目录下 package.json字段分析 name:包的名称,必须是唯一的,由小写英文字 ...
- Spring Boot 前世今生
Spring Boot 2.0 的推出又激起了一阵学习 Spring Boot 热,就单从我个人的博客的访问量大幅增加就可以感受到大家对学习 Spring Boot 的热情,那么在这么多人热衷于学习 ...