Integer类和int的关系以及自动装箱

什么是自动拆装箱:
    假设我们想定义一个整型的数组列表(集合),而尖括号里的类型不允许是基本数据类型,也就是说,不允许写成ArrayList<int>,这里就必须用到Integer类.像这样的情况,需要将int这样的基本数据类型转换为对象.所有的基本类型都有一个与之对应的类.例如:Integer对应的基本数据类型int.通常这些类型称之为包装器.他们的名字和基本数据类型有些小的差别:Integer,Long,Float,Double,Short,Byte,Character,Void和Boolean(前6个都派生于公共的超类Number).对象包装器是不可变的,一旦构造了包装器,就不允许更改包装在其中的值(这句话很重要).
    下面看一段代码:
                            
我们发现用同样的方法得到的值不一样.首先这是一个自动装箱的过程,这个过程是调用的Integer类的Integer valueof(int i)方法,看一下这个方法的源码:
                        

通过这段代码我们大致的知道:传进来的int数 i 在IntegerCache.low和IntegerCatch.high的时候就直接返回数组中的对象,在这个返回外的时候会调用Integer的构造方法,在堆内存中创建一个新的对象.这个范围具体是多少呢?我们继续看下面的代码:

 所以自动装箱的过程是这样的:当被装箱的int类型值为-128~127这个范围的时候是直接在缓存中(常量池)取值,在这个范围外的就需要new对象了.
弄清楚了这个我们在来看本文最初的代码就很简单了: i 和 j 比较的时候是在-128~127这个范围内的,所以都是在常量池里面取,所以是相等的.当 c 和 d 比较的时候,没有在此范围内,c d 都在对内存中开辟了空间,地址值也不一样,所以结果是false    


另外在来看看下面的代码:
                
相信大家都很容易看出来为什么输出 a 的时候是 3,是因为基本数据类型传参的时候是传的值,那么为什么输出 b 的时候会是 250 呢? 在本文的最初写了一句话:对象包装器是不可变的,一旦构造了包装器,就不允许更改包装在其中的值,所以我们不能用包装类来实现修改数值的方法.实在想要修改就参照下面的图片:

猜你喜欢

转载自blog.csdn.net/iteen/article/details/80620299