每章一点正能量:每当你想要放弃的时候,就想一想是为了什么才一路坚持到如今。html
最近在回顾复习Java基础中的一些知识点,发现了一些之前见过可是没有留意却特别有意思的知识特性,好比此次想分享的Java中一个常见的特性:自动装箱与拆箱
。这个知识点和特性其实在咱们开发过程当中常常会遇到。同时咱们也会去使用一些基本数据类型或者是封装数据类型,可是对于他们之间的一些转换等特性可能不是特别清楚。也可能出如今咱们的面试中。本章部份内容从源码中解读一些自动装箱与拆箱的原理,以及会出现的一些陷阱已经性能等。若有错误还请你们及时指出~java
问题:github
Java把内存划分红两种:一种是栈内存,另外一种是堆内存。面试
int是基本类型,直接存数值;而 Integer是类,产生对象时用一个引用指向这个对象。数据库
封装类位于java.lang包中。编程
封装类是引用传递而基本类型是值传递数组
基本类型的变量和对象的引用变量都是在函数的栈内存中分配 ,而实际的对象是在存储堆内存中缓存
咱们来看下他们之间有哪些区别: bash
八种基本数据类型分别是:byte、char、boolean、int、short、float、double、long; 对应的封装类型分别是:Byte、Character、Boolean、Integer、Short、Float、Double、Long。
基本类型 | 封装类型 | 字节长度 | 默认值 |
---|---|---|---|
boolean | Boolean | 1 | false |
byte | Byte | 1 | 0 |
char | Character | 2 | u0000 |
short | Short | 2 | 0 |
int | integer | 4 | 0 |
long | Long | 8 | 0l或0L |
float | Float | 4 | 0.0f或0.0F |
double | Double | 8 | 0.0 |
在巩固了上面的基础知识点以后,咱们再来看下另外的一个知识点 "=="和"equal()"
这两个判断符在比较基本数据类型和封装类型的时候会作的一些事情。
" == ":比较的是基本数据类型,比较的是它们的值
"equals()": 比较的是引用数据类型,根据不一样的数据类型调用不一样的equals方法。在特殊状况下能够重写equals方法。
a==b并不能判断a等于b,而是判断是否为同一个Object。若是咱们要判断他们的值怎么作呢?用equal或者Objects.equals()(JDK1.7以后新加 的语法)
Objects.equals有什么好处呢?
若是用a.equals(b) 若是a是null 的话,还会抛出空指针异常。可是用Objects.equals就没有问题。所以咱们在使用引用类型的时候须要注意,当咱们在赋值的时候,两个变量都是引用同一个Object。
咱们以 int与Integer
做为例子,看下"=="和"equal()"方法:
1)基本型和封装类型进行"=="运算符的比较,封装类型将会自动拆箱变为基本型后再进行比较,所以Integer(0)会自动拆箱为int类型再进行比较。
2)两个Integer类型进行"=="比较,若是其值在-128至127,那么返回true,不然返回false, 这跟Integer.valueOf()的缓冲对象有关,后面会说。
3)两个封装类型进行equals()比较,首先equals()会比较类型,若是类型相同,则继续比较值,若是值也相同,返回true。
4)基本型封装类型调用equals(),可是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。Java语言规范中说道:在许多状况下包装与解包装是由编译器自行完成的(在这种状况下包装称为装箱,解包装称为拆箱)。 通俗的理解:装箱:基本类型转换成封装类型, 拆箱:封装类型转换成基本类型 这么一个过程。在上面有介绍八种基本类型和对应的封装类型。下面以Integer与int之间的转换做为理解:
Integer a = 2; //Boxing
复制代码
简单的理解:将2装在一个箱子里,这个箱子的类型是Integer 。箱子这里面装的数值就是2,咱们就完成了一次装箱操做。并把a指向2这个箱子。
Integer b = new Integer(2);//Boxing
复制代码
显示装箱。生成一个新的箱子 new Integer(); 而且这个箱子的值为2.并且让b指向这个箱子。
故名思议就是将对象从新转化为基本数据类型
int v = a.intValue(); //Unboxing
复制代码
简单的理解:将里面int的值取出来。拆箱有个很典型的用法就是在进行运算的时候:由于对象时不能直接进行运算的,而是要转化为基本数据类型后才能进行加减乘除。
例如:
Integer c = 5;
System.out.print(c--);//进行计算时隐含的有自动拆箱
复制代码
经过第四点咱们知道装箱拆箱的基本概念知识,下面咱们一样以Integer 为例,进入源码里面看看里面的乾坤。
咱们首先看下Integer的大小。
能够看出,其定义了Integer的最大值为2^31-1,最小值为-2^31。Integer的基本数据类型为int。
再来看看Integer中的valueOf()方法。
能够看出valueOf()方法是个静态方法。当传进来的变量值在一个区间以内,直接用IntegerCache.cache[]数组里面的数返回,不然new一个新对象。
接着咱们来看看IntegerCache类。其实也是会出现坑的一个地方。
接着来讲下Integer这儿的一个坑,也是比较有意思的地方。
初始化Integer后,IntegerCache会缓存[-128,127]之间的数据,这个区间的上限能够配置,取决于java.lang.Integer.IntegerCache.high这个属性,这个属性在VM参数里为-XX:AutoBoxCacheMax=2000进行设置调整或者VM里设置-Djava.lang.Integer.IntegerCache.high=2000。因此Integer在初始化完成后会缓存[-128,max]之间的数据。cache属于常量,存放在java的方法区中。
一样,在Long,Byte,Short,咱们也能够看到缓存,其缓存数据长度均是-128到127。这里不作展开。
另外其余陷阱: 如:
System.out.println(Integer.valueOf(null));
复制代码
Integer对象的值能够为null,因此编译器检查时不会出现检查时异常,可是在转换成int的时候就会抛出空指针异常。
咱们经过几个经典的问题,来看看你们到底理解了装箱与拆箱
的知识点没。
答案:true。 等号的左边是一个Object右边是一个数值,Object和数值怎么会相等的呢?Java的编译器很聪明,它会本身去作装箱和拆箱的操做。这边它将new Integer(5)作的是Unboxing,它会里面的value取出来,这时候发现取出来的5等于右边,因此就为true。
答案:false。 new Integer(5) 就是新建一个箱子,这个箱子的值就是5。 == 是判断这两个箱子是否是同一个箱子,不是说里面的值是否是同样.因此是false。由于他们不是同一个箱子。
答案: true。 Integer.valueOf(5)它会返回一个箱子给咱们,箱子里面的值是5。可是在返回这个箱子给咱们的时候,可能会新建一个新的箱子给咱们,也可能会使用现有的一个箱子给咱们。因此Integer.valueOf(5) == Integer.valueOf(5)。什么状况下才会相等呢?只有当系统已经将2这个箱子创建好了,而且缓存起来的状况下。会把箱子的引用同时发给等号的左边与右边。这样的状况,他们才会互相相等。Integer.valueOf() 是系统给咱们分配的一个箱子,咱们发现,每次调咱们的箱子时候,系统都给了同一个箱子。这个咱们的 Integer.valueOf(5) == Integer.valueOf(5)
可是: 可能为false。咱们在上面介绍过,在low和high之间,它会返回一个系统已经生产的cache,不然它会生产一个新的出来。看源码能够看到low = -128 high = 127。因此当它的值超过了区间后,它就会返回新的箱子,因此就会为false。
咱们不用5改用200试一试。
Integer.valueOf(200) == Integer.valueOf(200)
复制代码
答案:false。 说明系统对小的数字会使用系统分配的箱子,对于大的数字,系统会从新new一个箱子。面试的时候,能够回答,他们可能相等,也可能不相等。是有系统决定的。
答案: true。 intValue()作了一个拆箱的操做,将里面的值5取出来,值5等于5,因此是true。
答案:true。 这里咱们没有用==而是用equals,equals判断相等是判断里面的值是否是相等,而不是判断这个箱子是否是同一个,因此咱们的答案是true。咱们来看看equals的源码。判断里面的值是否是相等。
本章节主要简单介绍了自动装箱与拆箱
的相关知识,但愿对你们有所帮助~ 从此我会在每张文章开头增长 每章一点正能量 ,文末增长5个编程相关的英语单词 学点英语。但愿你们和我同样天天都能积极向上,一块儿学习一同进步!
欢迎关注公众号:Coder编程 获取最新原创技术文章和相关免费学习资料,随时随地学习技术知识!
参考文章: