小美老师

首席讲师

Java自动装箱和拆箱原理分析

 2016-05-19 10:11  74人

 1.Java封装类

对于简单类型数据,为了和Java面向对象的思想一致,Java对它们进行了封装,使它们都有相应的封装类

简单数据类型

封装类

          boolean

          Boolean

          byte

          Byte

          short

          Short

          int 

          Integer

          long

          Long

          char

          Character

          float

          Float

          double

          Double

2.Java自动装箱和拆箱定义

Java 1.5中引入了自动装箱和拆箱机制:

自动装箱:把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质,可以调用toString()、hashCode()、getClass()、equals()等方法。

        Integer a=3;//这是自动装箱

其实编译器调用的是static Integer valueOf(int i)这个方法,valueOf(int i)返回一个表示指定int值的Integer对象,那么就变成这样: 

        Integer a=3;   =>    Integer a=Integer.valueOf(3);

拆箱:跟自动装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为基本类型的数据。

         int i = new Integer(2);//这是拆箱

编译器内部会调用int intValue()返回该Integer对象的int值

注意:自动装箱和拆箱是由编译器来完成的,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。

一个简单的例子

1. Integer integer1 = 100;  

2. Integer integer2 = 100;  

3. System.out.println("integer1==integer2: " + (integer1 == integer2));// true  自动装箱的两个缓存中的 Integer对象的引用比较  

4. System.out.println("integer1.equals(integer2): " + (integer1.equals(integer2)));// true  

5. System.out.println("integer1.compare(integer2): " + integer1.compareTo(integer2));// 0      

6. Integer integer3 = 200;  

7. Integer integer4 = 200;  

8. System.out.println("integer3==integer4: " + (integer3 == integer4));// false 自动装箱的两个new Integer的引用比较  

9. System.out.println("integer3>integer4: " + (integer3 > integer4)); // false 将两个对象拆箱,再比较大小  

10. System.out.println("integer3.equals(integer4): " + (integer3.equals(integer4)));// true  

11. System.out.println("integer3.compare(integer4): " + integer3.compareTo(integer4));// 0     

12. Integer integer5 = new Integer(100);  

13. Integer integer6 = new Integer(100);  

14. System.out.println("integer5==integer6: " + (integer5 == integer6)); // false 两个不同的Integer对象引用的比较  

15. System.out.println("integer5.equals(integer6): " + (integer5.equals(integer6)));// true  

16. System.out.println("integer5.compare(integer6): " + integer5.compareTo(integer6));// 0      

17. int int1 = 100;  

18. System.out.println("integer1==int1: " + (integer1 == int1));// true  Integer缓存对象拆箱后与int比较  

19. System.out.println("integer1.equals(int1): " + (integer1.equals(int1)));// true  

20. System.out.println("integer1.compare(int1): " + integer1.compareTo(int1));// 0        

21. int int2 = 200;  

22. System.out.println("integer3==int2: " + (integer3 == int2));// true  Integer对象拆箱后与int比较  

23. System.out.println("integer3.equals(int2): " + (integer3.equals(int2)));// true  

1. System.out.println("integer3.compare(int2): " + integer3.compareTo(int2));// 0   

3.源码分析

1. public static Integer valueOf(inti) {    

2.     if(i >= -128 &&i <=IntegerCache.high) 

3.        return IntegerCache.cache[i + 128];    

4.     else  

5.        return new Integer(i);

6. }    

         IntegerCache内部类

1. private static class IntegerCache {static final  

2.     static final inthigh;

3.     static final Integer cache[];  

4.   

5.     static {

6.         final int low = -128

7.         int h = 127;

8.         if (integerCacheHighPropValue !=null) {  

9.             int i = Long.decode(integerCacheHighPropValue).intValue(); 

10.             i = Math.max(i, 127); 

11.             h = Math.min(i, Integer.MAX_VALUE - -low);  

12.         }  

13.         high = h; 

14.         cache =new Integer[(high - low) + 1];  

15.         int j = low;  

16.         for(int k = 0; k <cache.length; k++)  

17.             cache[k] =new Integer(j++);

18.     }  

19. }  

 用integerCacheHighPropValue变量设置自动装箱池大小,设置-XX:AutoBoxCacheMax=<size>选项再次测试<3>中代码

在eclipse中,选中源文件,右键Run as—>RunConfiguratio--->Arguments,在VM arguments中做以下设置:

          

         运行,控制台报错:Unrecognized VM option 'AutoBoxCacheMax=256'

 找到JAVA_HOME/jre/lib/i386/jvm.cfg, 只需要把-server和-clent换个位置就行了.

分享到: