我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java的自动装箱和拆箱源码分析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java的自动装箱和拆箱源码分析

这篇“Java的自动装箱和拆箱源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java的自动装箱和拆箱源码分析”文章吧。

    什么叫装箱 & 拆箱?

    将int基本类型转换为Integer包装类型的过程叫做装箱,反之叫拆箱。

    首先看一段代码

    public static void main(String[] args) {    Integer a = 127, b = 127;    Integer c = 128, d= 128;    System.out.println(a == b); // true    System.out.println(c == d); // false}

    不知道还有没有人不知道这段代码出现true和false的原因。由此我们引出了Java装箱的这个操作。我们带着疑问去进行分析。

    装箱(valueOf())

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

    我们可以发现,在最开始有一个判断,如果这个值的范围在[-128,127]之间,那么就从这个缓存(Integer数组)中取,如果不在这个范围那么直接new一个。

    为什么要有[-128,127]的缓存?

    我说说的理解,因为在我们的业务中,可能存在各种状态和标识等Integer类型的字段,这些值一般都是0,1,2,3之类的,而且出现的比较频繁,如果没有缓存,那么就需要频繁的new对象,然后再释放,就非常消耗内存空间,所以对于这个缓存就出现了,可以极大的帮助我们优化一些空间上的浪费。

    为什么是[-128,127]?

    这个我看了一下,具体为什么这里就不详说了,主要还是依赖计算机基础知识,在你了解了什么是原码、反码、补码。就很容易知道为什么是这个范围区间了。

    这个值也是可以通过启动参数进行更改的。

    -XX:AutoBoxCacheMax=(size)

    自动装箱带来的性能问题

    那么看到现在你应该明白上面代码出现不同结果的原因了,那么你有没有想过,比如我们业务中一个for循环中,出现了统计数据类似这样的操作,如果存在自动装箱,那么会出现什么问题?我们看下面一段代码。

    public static void main(String[] args) {    long startTime = System.currentTimeMillis();    Integer count = 0;    // int count = 0;    for (int i = 0; i < 5000000; i++) {        count += i;    }    System.out.println("计算时长:" + (System.currentTimeMillis() - startTime) + " ms");}// 执行结果:// Integer 计算时长:51 ms// int 计算时长:6 ms

    那么通过执行结果可以明显的发现自动装箱频繁的new对象、分配内存,造成时间和空间上的性能损耗。

    小总结

    通过上面的源码阅读和测试分析,我们可以得出结论,我们平时在进行计算统计,或者方法入参的时候,应该尽量的避免这种类型转换的问题。来提升我们整个代码的执行效率。

    拆箱(intValue)

    拆箱总体没有什么复杂的逻辑,直接返回这个数值的基本类型。

    补充:自动装箱、拆箱总是会发生吗?

    其实不一定。看下面的一段示例代码,输出结果已被注释在输出语句后面。

    public static void main(String[] args) {// TODO 自动生成的方法存根Integer a = 1;Integer b = 2;Integer c = 3;Integer d = 3;Integer e = 321;Integer f = 321;Long g = 3L;System.out.println(c==d);//true//包装类的==在没有遇到算术运算的情况下不会自动拆箱System.out.println(e==f);//falseSystem.out.println(c==(a+b));//trueSystem.out.println(c.equals(a+b));//trueSystem.out.println(g==(a+b));//true//equals方法不会处理数据转型关系System.out.println(g.equals(a+b));//false}

    发生自动装箱、拆箱的情况如下:

    自动装箱:基本类型赋值给包装类型。如:Integer i1 = 1;

    自动拆箱:

    1. 包装类型赋值给基本类型。如:int i2 = new Integer(1);

    2. int类型与Integer类型比较。int类型与Integer类型比较如果值相等则结果总是为true。

    3. Integer类型遇到算术运算

    但是为什么在上例中,System.out.println(c==d);与System.out.println(e==f);输出的结果不一样呢?

    主要是因为Integer.valueOf()方法。Integer的部分源码贴在下面:

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

    IntegerCache 是Integer的静态内部类,valueOf()是包装方法。从源码中可以看出,cache是一个缓存数组,当valueOf()方法的入参i在[-128,127]区间内,就会返回缓存数组中的Integer值,否则会重新new一个Integer。

    这就是System.out.println(c==d);与System.out.println(e==f);输出结果不同的原因。c和d在缓存区间内,所以返回的是同一个引用;而e和f不在缓存区间内,返回的都是new Integer,已经不是同一个引用。

    以上就是关于“Java的自动装箱和拆箱源码分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Java的自动装箱和拆箱源码分析

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Java的自动装箱和拆箱源码分析

    这篇“Java的自动装箱和拆箱源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java的自动装箱和拆箱源码分析”文章吧
    2023-06-30

    Java自动拆装箱的示例分析

    这篇文章将为大家详细讲解有关Java自动拆装箱的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、拆装箱概念所谓的拆装箱,就是自从JDK1.5之后,java的基本类型和引用类型之间的相互转换。1.
    2023-05-31

    Java的自动装箱和拆箱的概念

    本篇内容主要讲解“Java的自动装箱和拆箱的概念”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java的自动装箱和拆箱的概念”吧!Java作为面向对象语言,有人认为所看到的都是对象,事实上,在J
    2023-06-17

    Java 自动装箱和自动拆箱的定义究竟是什么?(java自动装箱和自动拆箱的定义是什么)

    在Java编程中,自动装箱(Autoboxing)和自动拆箱(Unboxing)是两个非常重要的概念,它们极大地简化了基本数据类型和包装类之间的转换操作。一、自动装箱的定义自动装箱是指Java编译器在必要的时候自动将基本
    Java 自动装箱和自动拆箱的定义究竟是什么?(java自动装箱和自动拆箱的定义是什么)
    Java2024-12-16

    java自动装箱和自动拆箱的定义是什么

    自动装箱(Autoboxing)指的是Java编程语言中的一种特性,它允许将基本数据类型自动转换为对应的包装类类型。例如,当我们将一个int类型的值赋给一个Integer类型的变量时,编译器会自动将int类型的值包装为一个Integer对象
    2023-10-27

    深入浅析Java中拆箱与自动装箱的原理

    这篇文章给大家介绍深入浅析Java中拆箱与自动装箱的原理,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。什么是自动装箱和拆箱自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象
    2023-05-31

    java编程中自动拆箱与自动装箱详解

    什么是自动装箱拆箱基本数据类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。 一般我们要创建一个类的对象实例的时候,我们会这样: Class a = new Class(parameter)
    2023-05-30

    深入理解java中的自动装箱与拆箱

    一、什么是装箱,什么是拆箱装箱:把基本数据类型转换为包装类。拆箱:把包装类转换为基本数据类型。基本数据类型所对应的包装类:int(几个字节4)- Integerbyte(1)- Byteshort(2)- Shortlong(8)- Longfloat(4)-
    深入理解java中的自动装箱与拆箱
    2018-06-17

    Java自动装箱、自动拆箱与Integer缓存怎么使用

    今天小编给大家分享一下Java自动装箱、自动拆箱与Integer缓存怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1
    2023-06-30

    Java中的装箱和拆箱是什么

    本篇内容介绍了“Java中的装箱和拆箱是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录装箱拆箱==null总结装箱八大基本类型都有一
    2023-06-20

    java装箱和拆箱的概念是什么

    Java装箱和拆箱是将基本数据类型转换为对应的包装类类型(装箱)和将包装类类型转换为对应的基本数据类型(拆箱)的过程。装箱(Boxing)是将基本数据类型转换为对应的包装类类型。当需要将基本数据类型赋值给包装类类型或者作为参数传递给方法时,
    2023-10-07

    一文探寻Java装箱和拆箱的奥妙

    Java中的装箱(boxing)和拆箱(unboxing)是指将基本数据类型与其对应的包装类之间进行转换的过程。本文就来带大家探索一下Java装箱和拆箱的奥妙吧
    2023-05-18

    JAVA正则表达式、包装类、自动装箱/自动拆箱及BigDecimal怎么用

    本篇内容介绍了“JAVA正则表达式、包装类、自动装箱/自动拆箱及BigDecimal怎么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1
    2023-06-29

    夯实Java基础系列2:Java自动拆装箱里隐藏的秘密

    本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看https://github.com/h3pl/Java-Tutorial喜欢的话麻烦点下Star哈文章首发于我的个人博客:www.how2pla
    2023-06-02

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录