java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言, 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台 (即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)) 的总称
这篇文章主要为大家深度剖析了 Java 拆箱装箱的相关资料, 具有一定的参考价值, 感兴趣的小伙伴们可以参考一下
先来看一段代码:
- public class Main{
- public static void main(String[] args){
- Integer num1 = 100;
- Integer num2 = 100;
- Integer num3 = 200;
- Integer num4 = 200;
- '''// 输出结果'''
- System.out.println(num1==num2);
- System.out.println(num3==num4);
- }
- }
猜猜结果是什么?
很多人都会认为结果全为 true, 但结果去不是这样的
true
false
为什么是这样的结果? 如果用内存来解释结果的话, num1 和 num2 指向的是同一个对象, 而 num3 和 num4 则指向的确是不同的对象接下来就告诉你为什么, 看一看 Integer 类型的 valueof 方法的源码:
- public static Integer valueOf(int i) {
- assert IntegerCache.high >= 127;
- if (i >= IntegerCache.low && i <= IntegerCache.high)
- return IntegerCache.cache[i + 128];
- return new Integer(i);
- }
其中 IntegerCache 的实现:
- '''// IntegerCache, 一个内部类, 注意它的属性都是定义为 static final'''
- private static class IntegerCache {
- static final int high; '''// 缓存上界, 暂为 null'''
- static final Integer cache[]; '''// 缓存的整型数组'''
- '''// 块, 为什么定义为块'''
- static {
- final int low = -128; '''// 缓存下界, 不可变了只有上界可以改变'''
- '''// high value may be configured by property'''
- '''// h 值, 可以通过设置 jdk 的 AutoBoxCacheMax 参数调整 (以下有解释), 自动缓存区间设置为[-128,N] 注意区间的下界是固定'''
- int h = 127;
- if (integerCacheHighPropValue != null) {
- '''// Use Long.decode here to avoid invoking methods that'''
- '''// require Integer's autoboxing cache to be initialized'''// 通过解码 integerCacheHighPropValue, 而得到一个候选的上界值'''
- int i = Long.decode(integerCacheHighPropValue).intValue();
- '''// 取较大的作为上界, 但又不能大于 Integer 的边界 MAX_VALUE'''
- i = Math.max(i, 127);
- '''// Maximum array size is Integer.MAX_VALUE'''
- h = Math.min(i, Integer.MAX_VALUE - -low);
- }
- high = h; '''// 上界确定'''
- '''// 就可以创建缓存块, 注意缓存数组大小'''
- cache = new Integer[(high - low) + 1]; //
- int j = low;
- for(int k = 0; k < cache.length; k++)
- cache[k] = new Integer(j++); '''// -128 到 high 值逐一分配到缓存数组'''
- }
- private IntegerCache() {}
- }
通过这两段代码可以看出, 在通过 valueof 方法创建 Integer 类型对象时, 取值范围为[-128,127], 数值在这个区间里, 指针指向 IntegerCache.cache 中已经存在的对象引用, 当数值超出这个范围, 就会创建一个新的对象
有一点需要注意的是, 并不是所有的类型都是这个范围, 看 Double 类型:
- public class Main {
- public static void main(String[] args) {
- Double i1 = 100.0;
- Double i2 = 100.0;
- Double i3 = 200.0;
- Double i4 = 200.0;
- System.out.println(i1 == i2);
- System.out.println(i3 == i4);
- }
- }
最终的输出结果:
false
false
具体为什么回事这样的结果, 大伙可以去看看源代码中 Double valueof 方法的实现, 其和 Integer valueof 方法不同, 是因为在某个范围内的整型数值的个数是有限的, 而浮点数却不是
注意, IntegerShortByteCharacterLong 这几个类的 valueOf 方法的实现是类似的
DoubleFloat 的 valueOf 方法的实现是类似的
拉下了一个, Boolean 类型的结果有两个 True or False 直接看源代码:
- public static Boolean valueOf(boolean b) {
- return (b ? TRUE: FALSE);
- }
而其中的 TRUE 和 FALSE 是这样定义的:
- public static final Boolean TRUE = new Boolean(true);
- '''/**'''
- '''* The <code>Boolean</code> object corresponding to the primitive'''
- '''* value <code>false</code>.'''
- '''*/'''
- public static final Boolean FALSE = new Boolean(false);
来源: http://www.phperz.com/article/18/0216/359018.html