java自动拆装箱怎么实现的,Java自动拆箱

  java自动拆装箱怎么实现的,Java自动拆箱

  00-1010什么是打包和拆包?首先,为什么一段代码装箱(valueOf())会有[-128,127]的缓存?为什么[-128,127]?自动打包引起的性能问题总结。intValue补充:自动打包和解包会一直发生吗?摘要

  00-1010将int基本类型转换为整数打包类型的过程称为打包,反之称为解包。

  

目录

公共静态void main(String[]args){ Integer a=127,b=127整数c=128,d=128system . out . println(a==b);//true system . out . println(c==d);//false}不知道还有没有人不知道这个代码的真假。这就引出了Java装箱的这个操作。我们带着问题分析。

 

  

什么叫装箱 拆箱?

公共静态整数值of(int I){//-128-127 if(I=Integer cache . low I=Integer cache . high)返回Integer cache . cache[I(-Integer cache . low)];返回新的整数(I);}我们可以发现,在开始的时候,有一个判断。如果该值的范围在[-128,127]之间,则从该缓存(整数数组)中取出。如果不在这个范围内,那么直接创建一个新的。

 

  00-1010我说的是理解,因为在我们的业务中,可能会有各种状态、标识等整数类型的字段,而这些值一般是0、1、2、3之类的,而且出现的频率很高。如果没有缓存,那么频繁的需要新的对象然后释放,会非常消耗内存空间,所以这个缓存的出现,可以极大的帮助我们优化一些空间浪费。

  00-1010我看过这个,但是不知道为什么在这里。我主要靠计算机基础知识,现在你知道什么是原码,什么是反码,什么是补码了。很容易知道为什么是这个范围。

  该值也可以通过启动参数进行更改。

  -XX:AutoBoxCacheMax=(size)

  00-1010所以现在你应该明白上面的代码有不同结果的原因了。那么你有没有想过,比如在我们业务中的一个for循环中,有一个操作的统计数据类似于这个。如果有自动打包,会出现什么问题?让我们看看下面的代码。

  public static void main(String[]args){ long start time=system . current time millis();整数计数=0;//int count=0;for(int I=0;我5000000;I){ count=I;} System.out.println(计算时间:(system . current time millis()-start time) ms );}//执行结果://Integer计算时间:51 ms//int计算时间:6 ms然后通过执行结果,我们可以明显的发现频繁自动装箱的新对象,分配内存,造成时间和空间上的性能损失。

  00-1010通过上面的源代码阅读和测试分析,我们可以得出结论,在做计算统计或者方法参与的时候,要尽量避免这种类型转换的问题。来提高我们整个代码的执行效率。

  00-1010拆箱没有复杂的逻辑。只需返回这个值的基本类型。

  00-1010不一定成立。请看下面的示例代码。输出结果已经在output语句后进行了注释。

  public static void main(string[]args){//TODO自动生成的方法stub Integer a=1;整数b=2;覆盖的

  er c = 3;Integer d = 3;Integer e = 321;Integer f = 321;Long g = 3L;System.out.println(c==d);//true//包装类的==在没有遇到算术运算的情况下不会自动拆箱System.out.println(e==f);//falseSystem.out.println(c==(a+b));//trueSystem.out.println(c.equals(a+b));//trueSystem.out.println(g==(a+b));//true//equals方法不会处理数据转型关系System.out.println(g.equals(a+b));//false}发生自动装箱、拆箱的情况如下:

  自动装箱:基本类型赋值给包装类型。如:Integer i1 = 1;

  自动拆箱:

  包装类型赋值给基本类型。如:int i2 = new Integer(1);int类型与Integer类型比较。int类型与Integer类型比较如果值相等则结果总是为true。Integer类型遇到算术运算但是为什么在上例中,System.out.println(c==d);与System.out.println(e==f);输出的结果不一样呢?

  主要是因为Integer.valueOf()方法。Integer的部分源码贴在下面:

  

 // private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }

IntegerCache 是Integer的静态内部类,valueOf()是包装方法。从源码中可以看出,cache是一个缓存数组,当valueOf()方法的入参i在[-128,127]区间内,就会返回缓存数组中的Integer值,否则会重新new一个Integer。

 

  这就是System.out.println(c==d);与System.out.println(e==f);输出结果不同的原因。c和d在缓存区间内,所以返回的是同一个引用;而e和f不在缓存区间内,返回的都是new Integer,已经不是同一个引用。

  

 

  

总结

到此这篇关于如何通过源码了解Java的自动装箱拆箱的文章就介绍到这了,更多相关Java自动装箱拆箱内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: