前言
写这篇文章是因为在之前的项目中通过findbugs进行代码优化,爆出的问题。其实我们的代码中暗藏危机,只是没有暴露出来而已
我这里使用jdk7
测试
|
|
运行结果
奇不奇怪,为什么会酱紫呢?
原因分析
我们都知道,在java中==
是比较的两个对象所指向的内存地址是否相等,而equals
方法比较的是值。如果按照这个理论,上面的结果中可以看出Integer a = 10;Integer b = 10;
这两个对象内存地址是同一个,也就是a和b两个引用指向同一个对象。而Integer a = 189;Integer b = 189;
中,a和b两个引用指向了两个不同的对象。真的是这样吗?为什么呢?
我们查看Integer
的源码:
通过这段源码可知:
- Integer是不可变对象,因为里面的value是final的
private final int value;
- -128到127之间的数据放到了
IntegerCache
中,IntegerCache
是static
的,因此将会放到常量池中作为缓存使用
因此可知,Integer a = 10;Integer b = 10;
这两个对象其实是从IntegerCache
缓存中取的,是同一个对象,地址肯定是相同的。而Integer a = 189;Integer b = 189;
是创建的两个新的对象,因此地址肯定不同啦
结论
永远不要用==
比较integer对象,以避免一些偶发不可预测的错误。
其他与此相关的知识点
Object
与Integer
比较
|
|
结果:
原因与上面的一样。
jdk8中上面代码编译可是不通过的吆
锁相关
我们都知道用于加锁的对象必须是不可变对象, 永远不要再不可变对象上加锁
因此永远不要再integer
对象上加锁,因为其实不可变对象private final int value;
。当integer重新赋值或者进行了计算以后,得到的值是新创建的对象。
结果