本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>
前言
- Integer作为一个包装类。你知道他通过
==
来比较会是什么效果吗? - 在官方设计中倾向于用
Integer.compareTo
来进行两个Integer
来实现内容的比较而不是使用==
问题描述
- 将128 构建给两个Integer对象。你觉得他们是相同的吗
- 将127构建给两个Integer对象。你觉得他们是相同的吗
public static void main(String[] args) throws InterruptedException {
Integer i1=128;
Integer i2=128;
Integer i3=127;
Integer i4=127;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
问题分析
- 上述的程序最终输出的分别是
false
、true
- 同样的操作为什么得到的不同的结果呢?除了值不同以外我真的看不出任何差别
- 对!就是值的问题。因为值不同导致不同的结果。
IntegerCache
- 在Integer中存在这样一个类
IntegerCache
,他的作用是将Integer
的数据进行缓存。
- 我们查看下他的源码中对该类的解释。他将
Integer
的-128~127的数据进行缓存。 - 换句话说,就是不在这个范围内的数据被视为冷数据。不做缓存处理。这里的缓存可以和
String
的常量池做一样的理解。 - 所以上面的
Integer i1=128;Integer i2=128
。实际上是在堆中的两个对象。因为128超出范围不做换出 - 而
Integer i3=127; Integer i4=127
在缓存范围内所以两个变量指向的是同一块地址。 - 这也就解释了为什么一个false、一个true了。
总结
- java中为什么要这么设计呢?
- 答:这样设计肯定是为了节省内存。因为加入缓存所以避免了该范围内的数据重复的在堆中创建
- 在java6以后可以通过
XX:AutoBoxCacheMax=num
来设置IntegerCache
区间的上限。 Integer i =100
会自动将100装箱成Integer
对象的即会调用Integer.valueOf
方法。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
-
这段代码中就是
Integer
类中装箱的操作。里面通过IntegerCache
实现我们本文的主题内容缓存范围。 -
拆箱:自动拆箱就是包装类型转换成基本数据类型。自动拆箱调用了Integer.intValue(),
-
装箱:自动装箱就是基本数据类型转换成包装类型。自动装箱过程调用了Integer.ValueOf(int),当int的范围是-128到127,是从Integer常量池中获取的,当超出这个范围是通过new产Integer对象.容易造成OOM