• 【转】Java自动装箱、拆箱、缓冲池


    JDK5以后 

    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迷题:等于,还是不等于?
     
    代码片段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指向缓冲池中的同一对象

  • 相关阅读:
    类之OCP(Open Closed Principle):开闭原则
    OO书籍 zz
    ObjectOriented Design Heuristics (zz)
    CSS3 filter(滤镜) 网站整体变灰色调
    js和jquery设置css样式的几种方法
    20条书写CSS代码
    js 调用向html追加内容
    移动端检测微信浏览器返回,关闭,进入后台操作
    防止表单重复提交的4种方法
    CSS浮动标准修复top塌陷和清除浮动及IE兼容标准格式
  • 原文地址:https://www.cnblogs.com/wuyou/p/3239676.html
Copyright © 2020-2023  润新知