java学习笔记:装箱和拆箱,包装器和缓冲池
3121 点击·0 回帖
![]() | ![]() | |
![]() | 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代码 private static class IntegerCache //定义类名 { static final int high; static final Integer cache[]; //cache缓存是一个存放Integer类型的数组 static //初始化 { final int low = -128; //最小值是固定的 int h = 127; //最大值暂时是127 if (integerCacheHighPropValue != null) //这段if代码不用深究,是一些判断,我看得眼花啊 { int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; //此时high就是127 cache = new Integer[(high - low) + 1]; //有256个元素 int j = low; //j的初始值是-128 for(int k = 0; k < cache.length; k++) //缓存区间数据 cache[k] = new Integer(j++); //将-128~127包装成256个对象存入缓存 } private IntegerCache(){} //构造方法,不需要构造什么 } 再来看valueOf方法 java代码 public static Integer valueOf(int i) { if(i >= -128 ;; i <= IntegerCache.high) { //如果i在-128~127之间,就直接在缓存中取出i的Integer类型对象 return IntegerCache.cache[i + 128]; } else { return new Integer(i); //否则就在堆内存中创建 } } 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] 明显a和b的地址是不一样的,不是同一个对象 代码片段2 public static void main(final String[] args) { Integer a = 100; Integer b = 100; System.out.println(a == b); } 解答: 结果输出true a和b指向了同一个对象,都是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); new了2次,都在堆内存中,但地址不一样 代码片段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) 所以a和b指向缓冲池中的同一对象 | |
![]() | ![]() |