• 深入理解Java自动装箱拆箱机制


    1、自动装箱与拆箱的定义

    装箱就是自动将基本数据类型转换为包装器类型(int-->Integer);

    拆箱就是自动将包装器类型转换为基本数据类型(Integer-->int)。

    Java中的数据类型分为两类:一类是基本数据类型,另一类是引用数据类型。如下图:

    基本类型 二进制位数 分装类
    int 32(4字节) Integer
    byte 8(1字节) Byte
    long 64(8字节) Long
    short 16(2字节) Short
    float 32(4字节) Float
    double 64(8字节) Double
    char 16(2字节) Character
    boolean 1(1/8字节) Boolean

     由上可知Java中的基本数据类型有八种分别是:int(4字节) byte(1字节) short(2字节) long(8字节) float (4字节) double(8字节) char(2字节) boolean(1byte)基本数据类型不是对象,不能使用对象的方法。将基本数据类型转换为对象就是自动装箱的过程。下面是基本数据类型与封装器类之间对应的关系。

    2、自动装箱

    public static void main(String[] args) {
            int a=3;
            //定义一个基本数据类型的变量a赋值3
            Integer b=a;
            //b是Integer 类定义的对象,直接用int 类型的a赋值    
            System.out.println(b);
            //打印结果为3
    }

    上面的代码中 Integer b=a; 一个对象怎么赋值成了基本数据类型的变量,其实这就是自动装箱的过程,上面程序在执行Integer b=a;的时候调用了Integer.valueOf ( int i ) 方法,Integer b=a; 这段代码等同于:Integer b=Integer.valueOf ( a ) 。下面是对 Integer.valueOf ( int i ) 方法简化后的源码:

    public static Integer valueOf(int i) {       
            if (i >= -128 && i <= 127)
                return IntegerCache.cache[i + 127];
                //如果i的值大于-128小于127则返回一个缓冲区中已存在的一个Integer对象
            return new Integer(i);
            //否则返回 new 一个Integer 对象
    }

     可以看到Integer.valueOf ( a )其实是返回了一个Integer的对象。因此由于自动装箱的存在Integer b=a 这段代码是没有毛病的。其实更简化的来写可以这样:Integer b=3,同样这段代码等价于:Integer b=Integer.valueOf (3 ) 。

    上面的这段代码中:IntegerCache.cache[i + 127],下面是简化后的源码:

    private static class IntegerCache {
     
            static final Integer cache[];
            //定义一个Integer类型的数组且数组不可变
            static {  
            //利用静态代码块对数组进行初始化。                     
                cache = new Integer[256];
                int j = -128;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
            }
     
      //cache[]原来是一个Integer 类型的数组(也可以称为常量池),value 从-128到127,
        public static Integer valueOf(int i) {   
            if (i >=-128 && i <= 127)        
                return IntegerCache.cache[i + (-IntegerCache.low)];
                //如果装箱时值在-128到127之间,之间返回常量池中的已经初始化后的Integer对象。
            return new Integer(i);
            //否则返回一个新的对象。
        }
    }

    从上面代码可知,IntegerCache 类在初始化的时候,生成了一个大小为 256 的integer 对象的常量池,并且integer.val 的值从-128-127之内,在自动装箱时候,基本数据类型在该范围内的,则直接从该缓存区获取对应的Ingeter对象并返回,超出该范围,则重新创建Ingeter对象并返回;

    3、自动拆箱

    public static void main(String[] args) {
            Integer b=new Integer(3);
            //b为Integer的对象
            int a=b;
            //a为一个int的基本数据类型
            System.out.println(a);
            //打印输出3。
        }

    当封装类自动拆箱时,其实 int a=b,自动调用了b.intValue()方法,这段代码等价于:int a=b.intValue(),来看看inValue()方法到底是什么,下面是源码:

    //自动拆箱时调用的方法,并直接返回基本数据类型
    public int intValue() {
         return value;
    }
    private final int value;
    //而自动装箱时,通过构造函数创建对应的封装类,并将该基本数据类型赋值给该类的静态成员变量
    public Integer(int value) {
        this.value = value;
    }

    4、相关题目

    自动装箱和拆箱已经解决了,看看下面的代码输出什么:

    public static void main(String[] args) {        
            //1
            Integer a=new Integer(123);
            Integer b=new Integer(123);
            System.out.println(a==b);//输出 false
            //分别创建两个封装类对象,比较的对象的引用类型变量,则不相等
     
            //2 
            Integer c=123;
            Integer d=123;  
            System.out.println(c==d);//输出 true
            //对于同一个值,且值在-128~127范围内,自动装箱时直接返回缓存区已存在的Ingeter对象,则他们的引用类型变量是相等的,c、f为指向同一个对象
     
            //3
            Integer e=129;
            Integer f=129;
            System.out.println(e==f);//输出 false
            //自动装箱时,值超过了-128~127范围内,重新创建Ingeter对象,则e、f为指向两个对象
            
            //4
            int g=59;
            Integer h=new Integer(59);
            System.out.println(g==h);//输出 true
            //当一个基本数据类型,跟封装类做对比时,封装类会自动拆箱成基本数据类型,然后再比较值得大小
        }

    原文:https://blog.csdn.net/MyArray/article/details/89381893

  • 相关阅读:
    Azure PowerShell (2) 修改Azure订阅名称
    Windows Azure Platform Introduction (11) 了解Org ID、Windows Azure订阅、账户
    Azure PowerShell (3) 上传证书
    Azure PowerShell (1) PowerShell入门
    Windows Azure Service Bus (2) 队列(Queue)入门
    Windows Azure Service Bus (1) 基础
    Windows Azure Cloud Service (10) Role的生命周期
    Windows Azure Cloud Service (36) 在Azure Cloud Service配置SSL证书
    Android studio 使用心得(一)—android studio快速掌握快捷键
    android 签名、混淆打包
  • 原文地址:https://www.cnblogs.com/ldcs/p/11884860.html
Copyright © 2020-2023  润新知