java学习笔记:装箱和拆箱,包装器和缓冲池

java学习笔记:装箱和拆箱,包装器和缓冲池
历史上的今天
回顾历史的今天,历史就像生活的一面镜子;可以了解历史的这一天发生的事件;借古可以鉴今;历史是不能忘记的.要记住历史的每一天
http://www.todayx.org/

jdk1.5以后
用Integer举例
Integer a = 3;              这是自动装箱
int     i = new Integer(2); 这是自动拆箱
就是基本类型和其对应的包装类型在需要的时候可以互相转换,具体过程由编译器完成
比如自动装箱:
Integer a=3;
其实编译器调用的是static Integer valueOf(int i)这个方法
查阅JDK知道,
valueOf(int i)返回一个表示指定的 int 值的 Integer 对象
那么就变成这样: Integer a=3;   =>    Integer a=Integer.valueOf(3);

对应的  int intValue()  返回该 Integer对象的int值,是拆箱

我们再来看Integer缓存, 
下面是IntegerCache类的源码

Java代码   收藏代码
  1. private static class IntegerCache   //定义类名  
  2. {    
  3.     static final int high;    
  4.     static final Integer cache[];   //cache缓存是一个存放Integer类型的数组  
  5.   
  6.     static  //初始化  
  7.     {    
  8.         final int low = -128;       //最小值是固定的  
  9.         int h = 127;                //最大值暂时是127  
  10.         if (integerCacheHighPropValue != null) //这段if代码不用深究,是一些判断,我看得眼花啊  
  11.         {    
  12.             int i = Long.decode(integerCacheHighPropValue).intValue();    
  13.             i     = Math.max(i, 127);    
  14.             h     = Math.min(i, Integer.MAX_VALUE - -low);    
  15.         }    
  16.         high = h;  //此时high就是127  
  17.   
  18.         cache = new Integer[(high - low) + 1];  //有256个元素  
  19.         int j = low;                            //j的初始值是-128  
  20.         for(int k = 0; k < cache.length; k++)   //缓存区间数据     
  21.             cache[k] = new Integer(j++);        //将-128~127包装成256个对象存入缓存  
  22.     }    
  23.     private IntegerCache(){}  //构造方法,不需要构造什么  
  24. }  

 

再来看valueOf方法

Java代码   收藏代码
  1. public static Integer valueOf(int i)   
  2. {    
  3.     if(i >= -128 && i <= IntegerCache.high)  
  4.     {  
  5.         //如果i在-128~127之间,就直接在缓存中取出i的Integer类型对象  
  6.         return IntegerCache.cache[i + 128];    
  7.     }      
  8.     else  
  9.     {  
  10.         return new Integer(i);  //否则就在堆内存中创建  
  11.     }      
  12. }   

 

valueOf方法会自动调用IntegerCache这个类,
IntegerCache初始化后内存中就有Integer缓冲池cache[]了,
-128~127区间的int值有其对应的的包装对象
java使用该机制是为了达到最小化数据输入和输出的目的,这是一种优化措施,提高效率
其他的包装器:
Boolean: (全部缓存)
Byte:    (全部缓存)

Character (   <=127 缓存)
Short     (-128~127 缓存)
Long      (-128~127 缓存)

Float     (没有缓存)
Doulbe    (没有缓存)

====================================================

知道了这个原理我们再来看一些网上关于java的有趣问题,就能知道答案了

下面我们对一网友帖子中的问题的做解答,我当时也是看到这个帖子才baidu学到这些内容的

http://xiaoyu1985ban.iteye.com/blog/1384191

主题:java迷题:等于,还是不等于?

代码片段1

public static void main(final String[] args) {  

    Integer a = new Integer(100);  

    Integer b = 100;  

    System.out.println(a == b);   

} 

解答:

结果输出 false

因为new Integer(100)是指明了再堆内存中创建对象

Integer b = 100; 这句是自动装箱,

得到的是Integer缓冲池中的对象,是这句代码return IntegerCache.cache[100 + 128]

明显ab的地址是不一样的,不是同一个对象

 

代码片段2

public static void main(final String[] args) {  

    Integer a = 100;  

    Integer b = 100;  

    System.out.println(a == b);   

} 

解答:

结果输出 true

ab指向了同一个对象,都是IntegerCache.cache[100 + 128]

 

代码片段3

public static void main(final String[] args) {  

    Integer a = 156;  

    Integer b = 156;  

    System.out.println(a == b);   

} 

解答:

结果输出 false

由于156大于128,它的包装对象不在缓冲池中,而是执行 return new Integer(156);

new2,都在堆内存中,但地址不一样

 

代码片段4

public static void main(final String[] args) {  

    Integer a = Integer.valueOf(100);  

    Integer b = 100;  

    System.out.println(a == b);   

}

解答:

结果输出 true

我们上面说过了,Integer b = 100 就相当于Integer b=Integer.valueOf(100)

所以ab指向缓冲池中的同一对象



历史上的今天
回顾历史的今天,历史就像生活的一面镜子;可以了解历史的这一天发生的事件;借古可以鉴今;历史是不能忘记的.要记住历史的每一天
http://www.todayx.org/

你可能感兴趣的:(java学习笔记:装箱和拆箱,包装器和缓冲池)