zoukankan      html  css  js  c++  java
  • java基础解析系列(二)---Integer

    java基础解析系列(二)---Integer

    前言:本系列的主题是平时容易疏忽的知识点,只有基础扎实,在编码的时候才能更注重规范和性能,在出现bug的时候,才能处理更加从容。

    目录

    自动装箱和拆箱

    • 装箱就是自动将基本数据类型装换为包装器类型,拆箱就是自动将包装器类型转换为基本数据类型。
    Integer i=666;//装箱
    int n=i;//拆箱
    

    分析

        private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }
    
            private IntegerCache() {}
        }
    
    • Integer类里面有个静态内部类IntegerCache,IntegerCache里面维护一个Integer类型的数组,默认情况下缓存-128到127的Integer对象
    • 缓存的范围可以通过-XX:AutoBoxCacheMax=size参数来设置
    • 注意缓存策略只有只有在装箱的时候起作用

    实验一

    public static void main(String[] args) {
           Integer i1=new Integer(127);
           Integer i2=new Integer(127);
           System.out.println(i1==i2);
           //false
        }
    
    • 实验表明通过new来创建的对象,因为是在堆中的两个空间,所以显然是不同的

    实验二

    public static void main(String[] args) {
            Integer i1=127;
        }
    
    • 对其进行反汇编

    • 实验表明自动装箱的效果等效于调用Integer的valueOf方法
     public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    
    • 通过源码发现,当i处于缓存的范围内的时候,使用的缓存的cache数组中的对象,超出范围后,是创建一个新的对象

    实验三

    public static void main(String[] args) {
           Integer i1=127;
           Integer i2=127;
           System.out.println(i1==i2);
        //true
        
    }
    
    • 实验表明通过自动装箱的情况下,i1==i2,也就是指向的是同一个对象

    实验四

    public static void main(String[] args) {
           Integer i1=Integer.valueOf(127);
           Integer i2=127;
           System.out.println(i1==i2);
           //true
        }
    
    • 实验表明,自动装箱的效果和valueOf方法效果一致

    实验五

     public static void main(String[] args) {
           Integer i1=128;
           Integer i2=128;
           System.out.println(i1==i2);
           //false
        }
        
    
    • 实验表明当超出范围后,会重新创建对象

    实验六

    // -XX:AutoBoxCacheMax=128
    public static void main(String[] args) {
           Integer i1=128;
           Integer i2=128;
           System.out.println(i1==i2);
           //true
        }
    
    • 实验表明,AutoBoxCacheMax可以设置Integer的缓存范围的最大值

    实验7

     public static void main(String[] args) {
           Integer sum = 0;
    	sum=sum+128;
    }
    
    

    • 通过反汇编,发现在相加的时候,Integer会进行拆箱(intValue()),相加后,然后再进行装箱(valueOf())

    实验八

    public static void main(String[] args) {
    		t1();
    		t2();
    
    	}
    
    	public static void t1() {
    		Long start = System.currentTimeMillis();
    		Integer sum = 0;
    		for (int i = 130; i < 1000000; i++) {
    			sum = sum + i;
    		}
    		System.out.println(System.currentTimeMillis() - start);
    	}
    
    	public static void t2() {
    		Long start = System.currentTimeMillis();
    		int sum = 0;
    		for (int i = 130; i < 1000000; i++) {
    			sum = sum + i;
    		}
    		System.out.println(System.currentTimeMillis() - start);
    	}
    // 输出 10 3
    
    • 实验表明,通过Integer进行相加效率更慢,因为每一次循环,Integer会进行自动装箱自动拆箱,超出范围后每次装箱的时候还会重新创建对象,所以即消耗空间又消耗时间

    我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)

    作者:jiajun 出处: http://www.cnblogs.com/-new/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。

  • 相关阅读:
    解决Nginx不支持pathinfo的问题
    PHP获取当前服务器信息的基本语句
    权重结构的加权排序算法
    《深入探讨C++对象模型》笔记 二
    链表的一些常用操作
    invalidate作用
    GetMessage()和PeekMessage()区别
    C语言程序编译的内存分配
    assert() 宏用法
    开始写博客
  • 原文地址:https://www.cnblogs.com/-new/p/7469763.html
Copyright © 2011-2022 走看看