• 自动拆装箱


    前言

    我们知道Java共有8种基本数据类型int、byte、short、long、float、double、char、boolean,对应的包装类分别为Integer、Byte、Short、Long、Float、Double、Character、Boolean。既然有了基本数据类型,那么为什么还需要包装类呢。主要因为Java是一种面向对象的语言,很多地方需要使用对象而不是基本数据类型。比如在集合类中,我们无法将int、double等类型放进去,因为集合的容器要求元素是Object类型。为了让基本数据类型也具有对象的特征,就出现了包装类型,相当于将基本数据类型"包装起来",使得基本数据类型具有对象的性质,并且为其添加了属性和方法,丰富了基本数据类型的操作。

    什么是自动拆装箱

    • 装箱: 就是把基本数据类型转化成对应的包装类
    • 拆箱: 就是把包装类型转化成对应的基本数据类型
    • 自动装箱: 就是将基本数据类型自动转换成对应的包装类
    • 自动拆箱:就是将包装类自动转换成对应的基本数据类型

    Java SE5之前如果要生成一个值为1的对象需要以下操作

    Integer i = new Integer(1);
    

    Java SE5之后,提供了自动拆装箱的功能,只需要以下操作

    Integer i = 1;#自动装箱
    int j =i;#自动拆箱
    

    自动拆装箱的实现原理

    举个例子

    public class Demo {
        public static void main(String[] args) {
            Integer i = 1;
            int j = i;
        }
    }
    

    字节码如下

    从以上的字节码来看,Java自动装箱调用了Integer.valueof()方法,自动拆箱调用了Integer.intValue()方法,其他包装类的自动拆装箱类似

    什么时候会用到自动拆装箱

    1.赋值
    Integer i = 1;#自动装箱,调用 Integer.valueOf()
    int j =i;#自动拆箱,调用 Integer.intValue()
    

    2.逻辑、算术运算

    Integer i = 1;
    int j = 2;
    int z = i + j;
    Boolean flag = i > j ? true : false;
    

    反编译后

    Integer i = Integer.valueOf(1);
    int j = 2;
    int z = i.intValue() + j;
    Boolean flag = Boolean.valueOf(i.intValue() > j);
    

    3.将基本数据类型放到集合里面

    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    

    反编译后

    ArrayList<Integer> list = new ArrayList();
    list.add(Integer.valueOf(1));
    

    4.函数调用

        public static void main(String[] args) {
            sum(2);
        }
        public static Integer sum(Integer i){
            return 0;
        }
    

    反编译后

      public static void main(String[] args)
      {
        sum(Integer.valueOf(2));
      }
      public static Integer sum(Integer i)
      {
        return Integer.valueOf(0);
      }
    

    自动拆装箱的问题

    我们来看下面的代码

    Integer i = 128;
    Integer j = 128;
    
    Integer x = 1;
    Integer y = 1;
    System.out.println(i==j);#false
    System.out.println(x == y);#true
    

    上面为什么会出现这样的结果,主要是由于Integer的缓存机制,我们来看一下Integer的源码

        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    
    

    Integer默认的缓存范围是 -128~127,当在这一范围时,不会生成新的对象;当超过这一范围后,才生成新的Integer对象。当然缓存机制不只有Integer有,比如:

    • Boolean,缓存了true/false对应实例,确切的说,返回两个常量实例Boolean.TRUE/FALSE
    • Short,缓存了 ~128-127的数值
    • Byte,数值有限,全部被缓存
    • Character,缓存范围‘ u0000 ' 到 ’ u007F '

    参考

    https://juejin.im/post/5b8de48951882542d63b4662

    https://www.cnblogs.com/dolphin0520/p/3780005.html

  • 相关阅读:
    3Dtouch 的实际应用详解(tableView中的应用)
    使用UIScrollView的zoomscale实现图片捏合放大
    SVN命令使用详解
    参数传递
    cookie文件路径
    XML和HTML之间的差异
    cssSelector元素定位方法
    如何调用一个数据完整的firefox浏览器
    Android生命周期详解
    android 利用countDownLatch实现主线程与子线程之间的同步
  • 原文地址:https://www.cnblogs.com/my12/p/10537173.html
Copyright © 2020-2023  润新知