• Integer&int,自动装箱&自动拆箱


    int 是基本数据类型它的值存在于栈中,Integer是int的包装类它的值存在于堆中,这些都是基础概念。

    下面代码示例是经常被面到的简单小问题,通过这个问题就可以知道什么是自动装箱什么是自动拆箱。

    package base.test;
    
    public class Test1 {
        public static void main(String[] args) {
            Integer i = 10;
            Integer j = 10;
            System.out.println(i == j);
    
            Integer a = 128;
            Integer b = 128;
            System.out.println(a == b);
    
            int k = 10;
            System.out.println(i == k);
    
            int kk = 128;
            System.out.println(a == kk);
    
            Integer m = new Integer(10);
            Integer n = new Integer(10);
            System.out.println(m == n);
            System.out.println(m+1 == n+1);
            
            Integer s = 126;
            Integer d = 1;
            int f = 127;
            System.out.println(f == (s + d));
    
            Integer r = 126;
            Integer x = 1;
            Integer g = 127;
            System.out.println(g == (r + x));
        }
    }
    View Code

    下边这一段是反编译后的代码。

    package base.test;
    
    import java.io.PrintStream;
    
    public class Test1
    {
      public static void main(String[] args)
      {
        Integer i = Integer.valueOf(10);
        Integer j = Integer.valueOf(10);
        System.out.println(i == j);
    
        Integer a = Integer.valueOf(128);
        Integer b = Integer.valueOf(128);
        System.out.println(a == b);
    
        int k = 10;
        System.out.println(i.intValue() == k);
    
        int kk = 128;
        System.out.println(a.intValue() == kk);
    
        Integer m = new Integer(10);
        Integer n = new Integer(10);
        System.out.println(m == n);
        System.out.println(m.intValue() + 1 == n.intValue() + 1);
    
        Integer s = Integer.valueOf(126);
        Integer d = Integer.valueOf(1);
        int f = 127;
        System.out.println(f == s.intValue() + d.intValue());
    
        Integer r = Integer.valueOf(126);
        Integer x = Integer.valueOf(1);
        Integer g = Integer.valueOf(127);
        System.out.println(g.intValue() == r.intValue() + x.intValue());
      }
    }
    View Code

    从反编译的中可以看到两个方法。Integer.valueOf(int);装箱方法把基本数据类型int封装成Integer。Integer.intValue(int);拆箱方法把Integer拆箱成int基本数据类型。

    以下是valueOf的源码,这个源码简单说如果装箱的int大于-128并且小于127就会从IntegerCache这个类的cache取出一个Integer对象。IntegerCache是Integer的一个内部类它通过static方法给数组cache赋值。也就是如果我们从valueOf中返回的Integer只要是在-128~127范围内的使用的都是cache数组中的缓存对象。

      public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    View Code
        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() {}
        }
    View Code

    intValue(int)方法则直接返回该Integer对象对应的基本数据类型值。

      public int intValue() {
            return value;
        }
    View Code

    下面我们挨个分析一段代码中的结果。

    Integer i = 10;Integer j = 10;System.out.println(i == j);//true

    两个基本数据类型10调用valueOf(int)升级成包装对象,10在cache范围内所有返回的是同一个对象。对象使用==判断的是堆内存地址所有为true。

    Integer a = 128;Integer b = 128;System.out.println(a == b);//false

    这个于上个的区别是128不在cache范围内,所以返回的是两个对象,两个对象的堆内存当然是不同的。

    int k = 10;System.out.println(i == k);//true

    当包装类型要和基本数据类型做运算包装类会拆箱为基本数据类型两个10是相等的。

    int kk = 128;System.out.println(a == kk);//true

    和上边一样,包装类型拆箱后就是基本数据类型128两个128是相等的。

    Integer m = new Integer(10);Integer n = new Integer(10);

    System.out.println(m == n);//false

    因为两个都是new出来的没有使用valueOf(int)自然都是在堆空间中有自己的地盘,所以不是同一个对象。

    System.out.println(m+1 == n+1);//true

    //当包装类型要和具体的数字运算就要拆箱两个11是相等的。

    Integer s = 126;Integer d = 1;int f = 127;System.out.println(f == (s + d));//true

    两个基本数据类型装箱后是两个对象,但是做加法运算就要在拆箱,127和127是相等的。

    Integer r = 126;Integer x = 1;Integer g = 127;System.out.println(g == (r + x));//true

    其实是把126,1,127都装箱然后。然后r和x要运算所以拆箱,g要和他俩的结果做运算也要拆箱。

  • 相关阅读:
    第一篇 HTML5打包APP之VMware15安装MAC(MAC OS 10.13)(OS X 10.14)原版可升级最新可解锁macOS Unlocker3.0(OS X 10.13)
    phpcms V9 网站域名变更后,刷新所有缓存后,栏目链接总是改不过
    ECShop——给商品详情页添加字段
    java webcontroller访问时报415错误
    SVN设置忽略上传属性
    Eclipse的Servers视图中无法添加Tomcat6/Tomcat7
    jquery $.each遍历json数组方法
    jquery 中json数组的操作 增删改
    JQuery获取input type="text"中的值的各种方式
    eclipse下把所有的文件都转换为UTF-8的方法
  • 原文地址:https://www.cnblogs.com/zumengjie/p/14125205.html
Copyright © 2020-2023  润新知