Java 的Integer、int与new Integer到底怎么回事?
先做一些总结,询问了些经验比较多的师傅,在这里表示感谢,然后自己总结下,今天的收获分享给大家:
1. int 和Integer在进行比较的时候,Integer会进行拆箱,转为int值与int进行比较。
2. Integer与Integer比较的时候,由于直接赋值的时候会进行自动的装箱,那么这里就需要注意两个问题,一个是-128<= x<=127的整数,将会直接缓存在IntegerCache中,那么当赋值在这个区间的时候,不会创建新的Integer对象,而是从缓存中获取已经创建好的Integer对象。二:当大于这个范围的时候,直接new Integer来创建Integer对象。
3. new Integer(1) 和Integer a = 1不同,前者会创建对象,存储在堆中,而后者因为在-128到127的范围内,不会创建新的对象,而是从IntegerCache中获取的。那么Integer a = 128, 大于该范围的话才会直接通过new Integer(128)创建对象,进行装箱。
实例分析
先看一个例子。
- public class Test {
- public static void main(String[] args) {
- Integer i = new Integer(128);
- Integer i2 = 128;
- System.out.println(i == i2);
- Integer i3 = new Integer(127);
- Integer i4 = 127;
- System.out.println(i3 == i4);
- Integer i5 = 128;
- Integer i6 = 128;
- System.out.println(i5 == i6);
- Integer i7 = 127;
- Integer i8 = 127;
- System.out.println(i7 == i8);
- }
- }
输出的结果为
- false
- false
- false
- true
我们一个一个的进行分析。
第一个情况:
- Integer i = new Integer(128);
- Integer i2 = 128;
i 是创建的一个Integer的对象,取值是128。
i2 是进行自动装箱的实例,因为这里超出了-128--127的范围,所以是创建了新的Integer对象。
那么i和i2都是Integer的对象咯。存储在堆中,分配的地址不同,在使用==进行判读的时候,由于双方都是对象,所以比较对象的地址是不是相同,这里的地址是不同的,因为new的时候会在堆中重新分配存储空间。
第二个情况:
- Integer i3 = new Integer(127);
- Integer i4 = 127;
i3 是创建的一个Integer的对象,取值是127.
i4 是进行自动装箱后生成的Integer的对象,其值-128<= i4 <= 127,所以在这里会与第一种情况有所不同,这个i4对象直接取缓存IntegerCache中的对应的对象,当然了也是对象。
那么i3和i4也都是对象咯,而且一个是缓存中的,一个自己new的,既然是对象那么==会比较其地址,因为都new出来的对象(一个是自己new出来的,一个是IntegerCache中new出来的对象),那么自然这两种情况下,在堆中分配的地址是不同的。
第三种情况:
- Integer i5 = 128;
- Integer i6 = 128;
i5是自动装箱产生的Integer的对象,但是其大小超过了范围:-128<=A <=127,那么,这里会直接自己创建该对象即:new Integer(128);
i6和i5类似的原理。
显然这两个对象都是new出来,在堆中的地址值是不同的,那么==的时候判读其地址是不是相等,也就不一样了。
第四种情况:
- Integer i7 = 127;
- Integer i8 = 127;
i7、i8是自动装箱产生的对象,其值都是127,那么这里很特殊的是127正好在-128<=i7<=127这个范围内的,那么会去IntegerCache中取,既然都是去IntegerCache中去取,那么自然该对象应该是一个对象,那么再堆中的地址应该是一样的,所以在判读两个对象是不是== 的时候,会输出true
源码解析
下面看下,Integer中的装箱的代码
当不用new Integer的时候,构造方法会通过这个方法来构造对象并返回。那么你看if中的代码就知道了,i>=IntegerCache.low&&i<=IntegerCache.high的时候,从IntegerCache中获取的实例,否则,直接new Integer(i);
下面就是IntegerCache的代码,其中low就是-128,high是默认的127,不过可以进行设置。
通过静态代码块直接创建了256个Integer的对象,从-128到127之间。
所以在第四种情况中,取出来的时候,都是经过了上面的return IntegerCache.cache[i + (-IntegerCache.low)]得到的最终的对象,因为在IntegerCache中是创建好的,不会从新new了,所以地址值是一样的,也就是同一个对象,所以为true。
Java 的Integer、int与new Integer到底怎么回事?的更多相关文章
- 转:JAVA里面的int类型 和Integer类型,有什么不一样
JAVA里面的int类型 和Integer类型,有什么不一样 原文链接:http://blog.csdn.net/wuxinliulei/article/details/11099565 java.l ...
- JAVA里面的int类型 和Integer类型,有什么不一样
JAVA里面的int类型 和Integer类型,有什么不一样 原创 2013年09月04日 23:15:11 标签: java / 2120 编辑 删除 JAVA里面的int类型 和Integer类型 ...
- 13-03 Java 基本类型包装类概述,Integer类,Character
基本类型包装类概述 将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据.常用的操作之一:用于基本数据类型与字符串之间的转换.基本类型和包装类的对应Byte,Short,Inte ...
- Java中的int和Integer
代码: public class Test{ public static void main(String[] args){ Integer i01 = 59; int i02 = 59; Integ ...
- Java中List, Integer[], int[]的相互转换
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class Mai ...
- Java 中的 int 与 Integer 用于 List<Integer> 时,以及通过打印变量检測程序执行和函数调用次数计数
总结一下近期做的东西中遇到的问题 1. Java 中的 int 与 Integer 用于 List<Integer> 时 两者之间的关系都是非常清楚的.int 是基本数据类型,存储的是值 ...
- 在java语言中int 和 Integer 有什么区别
在java语言中int 和 Integer 有什么区别 解答:int是基本数据类型,Integer是int的包装类,属于引用类型
- java中String,int,Integer,char、double类型转换
java中String,int,Integer,char.double类型转换----https://www.cnblogs.com/kangyu222/p/5866025.html
- Java学习之==>int和Integer的区别和联系
一.区别 1.类型 int是java中原始八种基本数据类型之一: Integer是一个类,包装整型提供了很多日常的操作: 2.存储位置和大小 int是由jvm底层提供,由Java虚拟机规范,int型数 ...
- java POJO中 Integer 和 int 的不同,用int还是用Integer
https://www.jianshu.com/p/ff535284916f [int和Integer的区别] int是java提供的8种原始类型之一,java为每个原始类型提供了封装类,Intege ...
随机推荐
- 生成TPC-H数据集
下载tpc-h tool 版本有点老,2.14.3,够用了. 在解压的文件夹下面cd到dbgen下,找到makefile.suite. ~/tpch_2_14_3$ cd dbgen~/tpch_2_ ...
- 20145325张梓靖 《Java程序设计》第16周课程总结
20145325张梓靖 <Java程序设计>第16周课程总结 实验报告链接汇总 实验一 "Java开发环境的熟悉" 实验二 "Java面向对象程序设计&quo ...
- g711u与g729比较编码格式
•g711a—编解码格式为G.711 alaw •g711u—编解码格式为G.711 ulaw (the default) •g729—编解码格式为G.729 •g729a—编解码格式为G.729a ...
- python 去除不可见的控制字符
尤其是在json load的时候,字符串中的不可见控制字符可能会导致错误,应该先对字符串进行控制字符过滤. 对网页文本同样适用,最好在处理网页文本时先进性控制字符清洗. Replace null by ...
- BZOJ 2333 【SCOI2011】 棘手的操作
题目链接:棘手的操作 网上的题解大部分都是在线用可并堆艹……但是树高严格\(\log\)的可并堆我不会啊……还是离线大法好…… 我们可以先把所有的合并操作用并查集给处理好,把得到的森林记录下来.然后, ...
- bin log、redo log、undo log和MVVC
logs innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过 ...
- Android 自定义注解(Annotation)
现在市面上很多框架都有使用到注解,比如butterknife库.EventBus库.Retrofit库等等.也是一直好奇他们都是怎么做到的,注解的工作原理是啥.咱们能不能自己去实现一个简单的注解呢. ...
- 【Python】使用codecs模块进行文件操作及消除文件中的BOM
前言 此前遇到过UTF8格式的文件有无BOM的导致的问题,最近在做自动化测试,读写配置文件时又遇到类似的问题,和此前一样,又是折腾了挺久之后,通过工具比较才知道原因. 两次在一个问题上面栽更头,就在想 ...
- Vue 组件设计
Vue 组件设计 Vue 作为 MVVM 框架一员,不管是写业务还是基础服务,都少不了书写组件.本文总结一下书写业务组件的一些心得. 为什么要写组件? 我们知道,只要是组件,就需要在引用的时候与 vi ...
- Eclipse开发Android应用 找不到平板
1.驱动安装正确2.平板的连接方式正确,不要用大容量存储/sd卡模式这个设置在4.3上很难找呀.设置->存储->点右上角的菜单 3.打开USB调试.4.上述问题都检查后,在eclipse里 ...