java integer 是final_初识Integer类(Java5之后)

一、从自动装箱开始

如果我们在创建一个Integer对象的时候,使用这样的方式:“Integer a = 3;”

那么Java是如何帮助我们创建一个对象的呢?是使用“Integer a = new Integer(3);”的简写吗?

答案很明显不是的。可以做一个实验简单的证明:3abb3cc5c06d9c9b0070dc9ab3f8ffdf.png1.1创建Integer

如果如上面所猜想的那样,那么对象c和d比较结果应该也是false,但是测试结果却是true。也就是说指向的是同一个对象。

在阅读Integer源码查找原因的时候,发现了其中竟然还有一个内部类:697f1acca8863c7a948efdcfa052b064.png1.2IntegerCache

看这个类的名称就知道,这是一个类似缓存的类,我们很轻易的就可以联想到,对象c和d应该与这个内置的缓存有关。

二、IntegerCache类e157d7b74f01f3983a642d41e8e7535b.png2.1IntegerCache源码

可以从代码中看出,系统默认帮我们创建了一个数组,其中保存有从-128到127的数字,当然你也可以去修改cache数组的上限:可以设置java.lang.Integer.IntegerCache.high属性并将其保存在sun.misc.VM类中的私有系统属性中,也可以由{@code -XX:AutoBoxCacheMax = }选项控制。

cache数组在Integer类加载的时候就已经准备好了,对象c和d的值刚好在cache数组的范围内,我们可以猜想对象c和d都是取自cache数组,下面可以同过一个实验证明:90776ae531322af6427917ad1ca7c477.png2.2猜想证明

取一个超过数组保存范围的数,得到的结果果然为false,此时c和d分别指向两个不同的对象。那么自动装箱到底是如何实现的呢?我继续在Integer类中查找使用到了IntegerCache类的方法,最终找到一个方法可以解释以上的现象:b50fb8646d66c3ef51dd03be79123215.png2.3自动装箱

在Integer自动装箱的时候,默认是调用的上图这个方法,首先判断i值的范围,如果在cache数组的范围内,则从数组中获取对象,在开始的实验中,由于对象c和d都在这个范围内,所以都是取自cache数组,故而指向的是同一个对象,所以比较的结果true。

在其后的证明实验中,对象c和d的取值超过了范围,所以返回的是一个新建的对象,就相当于是:Integer c = new Integer(200);所以得出的结果为false

三、传递

有上面得到的结论,不由得有了一个想法,如果我们更改c的值,那么d的值会不会也跟着变呢?

于是我做了一个测试8b8d77e8ce784529ebab1803cb092e01.png3.1改变值(1)

此时发现对象a和b所指向的地址不一致了,其中发生了什么呢?于是我继续在源码中查找答案:发现Integer类中,value变量是用final修饰的d76ac49eb2c2e45716ca4ecacecc9a5a.png3.2finalValue

原来Integer中的值是无法修改的,那么在我们将整数4赋值给变量b的时候发生了什么呢?

请看下面的实验43c04d47f8847ee2b0c3bbcb490b57b5.png3.3实验

虽然a和b所指向的地址不同了,那么到底是谁改变了地址呢?还是都改变了地址呢?

为搞明白这些问题,我额外增加了一个变量c,从结果可以发现,a的地址没有改变,改变的只有b,所以可以做出这样的结论:在“b=4;”这条语句中,其实相当于“b=valueOf(4);”

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值