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


    转自:http://www.2cto.com/kf/201202/118126.html

    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指向缓冲池中的同一对象
    摘自todayx.org

  • 相关阅读:
    JavaScript 类型转换
    Bjarne Stroustrup
    格拉丘纳斯的上下级关系理论
    成功者必须具备的三大技能
    ASP.NET/Perl.NET (转)
    iPhone/Mac ObjectiveC内存管理教程和原理剖析
    objectivec日期之间比较可用以下方法
    Centos下安装中文输入法
    C#中数字的四舍五入与只取整
    关于Application.Lock和Lock(obj)
  • 原文地址:https://www.cnblogs.com/apigiraffe/p/2685216.html
Copyright © 2020-2023  润新知