概述
同志们我又开始动笔了……
这两天在看Java的基础,看到Integer相关的内容,同时想起3年前一个大佬曾经面试过我这块,今天做个总结。
Java声称一切皆为对象,实际上也有一个例外:原始数据类型(Primitive Types)。一共有8个,分别是:boolean、byte 、short、char、int、float、double、long。他们不具备对象的特性,也没有自己的方法。
Integer,是int的包装类,从源码可知,Integer包含一个int型的字段value,用于存储数据,该value字段是final类型的,即生成了一个Integer对象后,该对象的数据值是不可更改的。还有两个常量MIN_VALUE表示int的最小值,MAX_VALUE表示int的最大值,即范围-2^31到2^31-1。
相比于原始数据类型,Integer封装了常用的一些方法,比如字符串转Integer,大小比较等。Java可以根据上下文,自动进行装箱拆箱,极大地简化大家平日的开发工作。
稍微有些开发经验的同学,应该也知道,Integer有个值缓存的机制。我们好好聊聊这个值缓存。
Java对象的创建,一般都是通过new的方式,Integer传统的方式也是如此。其实,通过观察和经验总结,发现大部分数据操作都集中在有限的、较小的范围内,那其实可以参考一般的缓存思想,虚拟机事先就提供好常用的Integer对象,那就可以有效的改进性能了。
虚拟机默认提供的Integer对象,值的范围是从-128到127。如果确定系统常用的数值超过这个范围,也可以通过-XX:AutoBoxCacheMax=N启动参数,来修改范围上限,目前没看到可以修改下限的方式,可以自己做缓存。
如果面试的时候,一时忘记了Integer的值缓存,我们可以怎么来证明呢。我自己想到的一个思路:如果对象确实是有缓存的,那么每次拿到的Integer对象应该都是相等的(内存地址相同);否则,每次新创建,那么他们的内存地址肯定是不同的。大家有其他思路的也可以说一下。
开发中,经常会遇到类型转换,比如String转Integer,一般我们会使用Integer提供的Integer.parseInt(str)或Integer.valueOf(str),那么这两个方法有什么区别吗?
先看一段测试代码:
发现Integer.parseInt(str)所花费的时间基本还是比较稳定的,没有剧增;Integer.valueOf("1")的时候也是比较稳定,Integer.valueOf("1000")的时候随着运行次数的增加,耗时就急剧增大。
为什么会这样呢?源码可以告诉我们答案。
Integer.valueOf(str)的源代码:
Integer.valueOf(str)是Integer的静态工厂方法,值缓存就是通过这个方法体现的。源码逻辑很清晰,如果 i 的值在范围内,则直接返回缓存的对象,如果超过范围,则new一个新对象,所以Integer.valueOf("1")始终返回的都是同一个对象,并且这个对象是存储在数组中的,数组访问是很快的。而Integer.valueOf("1000"),显然就是走了return new Integer(i)这句代码,只要调用Integer.valueOf("1000")就会创建一个Integer对象,创建对象相对于数组直接访问获取明显就慢多了,同时还占用了存储空间。这个方法最后返回的是Integer对象。
Integer.parseInt(str)的源码比较多,我就不贴上来了,大家有兴趣自己可以去看一下。大致思路就是通过把原始的字符串拆分出一个一个的字符然后通过计算得出最终的int值,需要考虑正负符号。方法返回的是int原始数据类型,没有创建Integer对象。所以调用这个方法,耗时大小主要就看这个算法了,显然JDK团队的能力是毋庸置疑的。
通过源码阅读和代码测试,我们做到了知其然知其所以然。
大部分同学还是以应用层开发为主,考虑更多的是便捷性和易用性。某些场景出于性能的考虑,则需要大家多动一下脑筋,选择更好的方式去完成需求。
--------猫玛尼分割线--------
最近在研究怎么用我的《猫玛尼》公众号给大家抽奖,等我研究好了抽一波!
最后
以上就是冷艳鲜花为你收集整理的double类型转integer类型_你确定了解Java的Integer吗?的全部内容,希望文章能够帮你解决double类型转integer类型_你确定了解Java的Integer吗?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复