Java的Integer与int互转
int转Integer
- ;
- Integer wrapperi = new Integer(i);
Integer转int
- );
- int i = wrapperi.intValue();
JDK1.5以后的int转Integer
JDK1.5以后,Java为我们提供了更为丰富的转换方法。
其中最值得一提的就是自动装包/自动拆包(AutoBoxing/UnBoxing)。
此功能大大丰富了基本类型(primitive type)数据与它们的包装类(Wrapper Class)
的使用。
由于AutoBoxing的存在,以下代码在JDK1.5的环境下可以编译通过并运行。
- ;
- Integer wrapperi = i;
还有其他方法?
JDK1.5为Integer增加了一个全新的方法:
- public static Integer valueOf(int i)
以下代码在JDK1.5的环境下可以编译通过并运行。
- ;
- Integer wrapperi = Integer.valueOf(i);
此方法与new Integer(i)的不同处在于:
方法一调用类方法返回一个表示指定的 int 值的 Integer 实例。
方法二产生一个新的Integer对象。
JDK API文档中对这个新的valueOf方法有明确的解释:
如果不需要新的 Integer 实例,则通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。
但这个解释有点晦涩难懂。为什么该方法有可能通过缓存经常请求的值而显著提高性能?
通过反编译工具查看valueOf方法。
- /*
- * 返回一个表示指定的 int 值的 Integer 实例。如果不需要新的 Integer 实例,则
- * 通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过
- * 缓存经常请求的值而显著提高空间和时间性能。
- * @param i an <code>int</code> value.
- * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
- * @since 1.5
- */
- public static Integer valueOf(int i) {
- ;
- && i <= 127) { // must cache
- return IntegerCache.cache[i + offset];
- }
- return new Integer(i);
- }
可以看到对于范围在-128到127的整数,valueOf方法做了特殊处理。
采用IntegerCache.cache[i + offset]这个方法。
从名字,我们可以猜出这是某种缓存机制。
进一步跟踪IntegerCache这个类,此类代码如下
- /*
- * IntegerCache内部类
- * 其中cache[]数组用于存放从-128到127一共256个整数
- */
- private static class IntegerCache {
- private IntegerCache(){}
- ) + 127 + 1];
- static {
- ; i < cache.length; i++)
- );
- }
- }
这就是valueOf方法真正的优化方法,当-128=<i<=127的时候,返回的是IntegerCache中的数组的值;当 i>127 或 i<-128 时,返回的是Integer类对象。
再举一个经常被提到的例子
- ;
- ;
- //print true
- System.out.println(i==j);
此时的 i=IntegerCache.cache[i + 128] = IntegerCache.cache[228],
同样j = IntegerCache.cache[j + 128] = IntgerCache.cache[228]
因此 Integer引用i中存储的是cache数组第228号元素的地址。同理j也是同一个cache数组的第228号元素的地址(因为cache是Integer的static数组,只有一个)。
i==j比较的是引用地址,因此返回true。
- ;
- ;
- //print false
- System.out.println(i==j);
此时的 i=new Integer(200); 同样j=new Integer(200) 。
两次都在堆中开辟了Integer的对象。
i 和 j 中存储的堆的对象地址是完全不同的。i==j 自然返回false。
引入缓存机制的作用何在?
接着上面的例子,假如我们在编程时大量需要值为100(100的范围在-128到127之间)的Integer对象。如果只能通过new来创建,需要在堆中开辟大量值一样的Integer对象。
这是相当不划算的,IntegerCache.cache很好的起到了缓存的作用。
当我们需要Integer i = 100的时候,直接从cache中取出第[100+128]号元素的地址赋值给引用i,再次需要Integer j = 100时,还是直接去这个地址赋值给j。是不是省去了在堆中不停的创建对象的代价了(空间,时间上的消耗都很大)。 这就是valueOf方法真正的提高性能之处。
正如JDK API文档对valueOf(int i)方法的描述,该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。
结论
valueOf(int i)的优化只针对于范围在-128到127的整数。
JDK1.5以后的Integer转int
由于UnBoxing的存在,以下代码在JDK1.5的环境下可以编译通过并运行。
- );
- int i = wrapperi;
附:AutoBoxing与UnBoxing带来的转变
在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀。
以下代码在JDK1.5中成为了可能,试想下在JDK1.5之前该如何实现这段代码?
- ;
- Collection collection = new ArrayList();
- collection.add(x);//AutoBoxing,自动转换成Integer.
- );
- ); //y + 2为UnBoxing,自动转换成int。之后再次转换为Integer。
此特性同样适用于Map
- Map map = new HashMap();
- ;
- );
- ;
- map.put(x,y + z);//x自动转换成Integer。y+z自动转换成int。之后再次转换为Integer。
Java的Integer与int互转的更多相关文章
- java中Integer与int装箱拆箱一点收获
示例代码: class BoxIntInteger { public static void main(String[] args) { Integer a = new Integer(10111); ...
- Java中Integer和int的异同
public void Test1() { int a = 128; Integer b = 128; Integer c = 128; //Integer会自动拆箱成int,所以为ture Syst ...
- java中Integer和int的区别(转)
int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...
- Java|从Integer和int的区别认识包装类
https://blog.csdn.net/darlingwood2013/article/details/96969339?utm_medium=distribute.pc_relevant.non ...
- Java中Integer 和 int的区别
基本概念的区分: 1.Integer 是 int 的包装类,int 则是 java 的一种基本数据类型 2.Integer 变量必须实例化后才能使用,而int变量不需要 3.Integer 实际是对象 ...
- Java中Integer与int对比的一些坑
Integer与int类型的关系 Integer是int的包装类,int的默认值是0,而Integer的默认值是null(我们经常在代码中使用的Integer.valueOf() 和xx.intVal ...
- Java的Integer和int有什么区别
Java是面向对象的编程语言,一切都是对象,但是为了编程的方便还是引入了基本数据类型,为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper cla ...
- Java 的Integer、int与new Integer到底怎么回事?
先做一些总结,询问了些经验比较多的师傅,在这里表示感谢,然后自己总结下,今天的收获分享给大家: 1. int 和Integer在进行比较的时候,Integer会进行拆箱,转为int值与int进行比较. ...
- java中Integer和int的区别
亲看这里 例子: public class Test { public static void main(String[] args) { Integer i = new Integer(128); ...
随机推荐
- $Poj3585\ Accumulation Degree$ 树形$DP/$二次扫描与换根法
Poj Description 有一个树形的水系,由n-1条河道与n个交叉点组成.每条河道有一个容量,联结x与y的河道容量记为c(x,y),河道的单位时间水量不能超过它的容量.有一个结点是整个水系的发 ...
- Java集合使用之next方法与remove方法 | Java集合使用之remove方法使用易错
Iterator接口的remove方法将会删除上次调用next方法时返回的元素. next方法和remove方法的调用具有相互依赖性,如果调用remove方法前没有调用next方法是不合法的. 错误使 ...
- 电脑端TIM登录时记住密码
为什么每次登录TIM时点了记住密码,下次再登录时还是记不住呢? 不是扫码就是还得输出密码,为这事愁了好多次, 最近终于发现如何记住密码了... 进入登录界面以后,点击左下角这个小图标>> ...
- 「SP122」STEVE - Voracious Steve 解题报告
SP122 STEVE - Voracious Steve 题意翻译 Problem Steve和他的一个朋友在玩游戏,游戏开始前,盒子里有 n个甜甜圈,两个人轮流从盒子里抓甜甜圈,每次至少抓 1个, ...
- Java线程池学习总结
一 使用线程池的好处 池化技术相比大家已经屡见不鲜了,线程池.数据库连接池.Http 连接池等等都是对这个思想的应用.池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率. 线程池提供了 ...
- Spring中Bean的实例化与DI的过程
引言 前文我们介绍了关于如何学习Spring的源码以及解析了spring中加载配置文件注册Beandefinition的过程.今天我们继续学习DI的过程. 创建实例和DI过程 IOC和DI都是对spr ...
- vim的常用指令(脑图)
将正在编辑的文件另存新文件名 :w newfilename 在正在编辑的文件中,读取一个filename :r filename 做了很多编辑工作,想还原成原来的文件内容 :e! 我在v ...
- 2019年全网最热门的123个Java并发面试题总结
前言 并发编程几乎是所有互联网公司面试必问的问题,并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密, ...
- Redis系列之----Redis的两种持久化机制(RDB和AOF)
Redis的两种持久化机制(RDB和AOF) 什么是持久化 Redis的数据是存储在内存中的,内存中的数据随着服务器的重启或者宕机便会不复存在,在生产环境,服务器宕机更是屡见不鲜,所以,我们希望 ...
- The command '/bin/sh -c unzip -o php-7.2.23-src.zip' returned a non-zero code: 1
Dockerfile 内容 #centos7 nginx php redis inotify FROM centos:7 MAINTAINER INFOBIRD RUN yum -y update & ...