Java 自动装箱和拆箱还有包装类的缓存问题

news2025/7/19 17:35:56

自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。JDK1.5 后,
Java 引入了自动装箱(autoboxing)/拆箱(unboxing)。

自动装箱:
基本类型的数据处于需要对象的环境中时,会自动转为“对象”。
我们以 Integer 为例:
在 JDK1.5 以前,这样的代码 Integer i = 5 是错误的,必须要通过 Integer i = new
Integer(5) 这样的语句来实现基本数据类型转换成包装类的过程;
而在 JDK1.5 以后,Java 提供了自动装箱的功能,因此只需 Integer i = 5 这样的语句
就能实现基本数据类型转换成包装类,这是因为 JVM 为我们执行了 Integer i =
Integer.valueOf(5)这样的操作,这就是 Java 的自动装箱。
自动拆箱:
每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用 intValue()、
doubleValue()等转型方法。
如 Integer i = 5;int j = i; 这样的过程就是自动拆箱。
我们可以用一句话总结自动装箱/拆箱:
自动装箱过程是通过调用包装类的 valueOf()方法实现的,而自动拆箱过程是通过调用
包装类的 xxxValue()方法实现的(xxx 代表对应的基本数据类型,如 intValue()、
doubleValue()等)。

自动装箱与拆箱的功能事实上是编译器来帮的忙,编译器在编译时依据您所编写的语
法,决定是否进行装箱或拆箱动作。

自动装箱:

Integer i = 100;//自动装箱
//相当于编译器自动为您作以下的语法编译:
Integer i = Integer. valueOf (100);//调用的是 valueOf(100),而不是 new Integer(100)

自动拆箱:

Integer i = 100;
int j = i;//自动拆箱
//相当于编译器自动为您作以下的语法编译:
int j = i.intValue();

所以自动装箱与拆箱的功能是所谓的“编译器蜜糖(Compiler Sugar)”,虽然使用这
个功能很方便,但在程序运行阶段您得了解 Java 的语义:

包装类空指针异常问题:

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

 

null 表示 i 没有指向任何对象的实体,但作为对象名称是合法的(不管这个对象名称存
是否指向了某个对象的实体)。由于实际上 i 并没有指向任何对象的实体,所以也就不可能
操作 intValue()方法,这样上面的写法在运行时就会出现 NullPointerException 错误。

包装类的缓存问题:

整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存
处理,其目的是提高效率。
缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间
的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱
过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接
获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。

下面我们以Integer类为例,看一看Java为我们提供的源码,加深对缓存技术的理解:

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

 这段代码中我们需要解释下面几个问题:
1. IntegerCache类为Integer类的一个静态内部类,仅供Integer类使用。
2. 一般情况下 IntegerCache.low为-128,IntegerCache.high为127,

IntegerCache.cache为内部类的一个静态属性:

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() {}
}

 由上面的源码我们可以看到,静态代码块的目的就是初始化数组cache的,这个过程会
在类加载时完成。

下面我们做一下代码测试

包装类的缓存测试:

public class Test3 {
    public static void main(String[ ] args) {
        Integer in1 = -128;
        Integer in2 = -128;
        System. out .println(in1 == in2);//true 因为 123 在缓存范围内
        System. out .println(in1.equals(in2));//true
        Integer in3 = 1234;
        Integer in4 = 1234;
        System. out .println(in3 == in4);//false 因为 1234 不在缓存范围内
        System. out .println(in3.equals(in4));//true

执行后的结果: 

 

 如下是Test3的内存分析:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2387753.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java-jdk8新特性Stream流

一、Stream流 是专业用于对集合或者数组进行便捷操作的。 1.1 Stream流的创建 主要分为Collection&#xff08;List与Set&#xff09;、Map、数组三种创建方式&#xff1a; //1.Collection集合的创建List<String> names new ArrayList<>();Collections.addAll(…

大语言模型 21 - MCP 自动操作 Figma+Cursor 实现将原型转换为代码

MCP 基本介绍 官方地址&#xff1a; https://modelcontextprotocol.io/introduction “MCP 是一种开放协议&#xff0c;旨在标准化应用程序向大型语言模型&#xff08;LLM&#xff09;提供上下文的方式。可以把 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 提供了一种…

QNAP NEXTCLOUD 域名访问

我是用docker compose方式安装的&#xff0c;虽然不知道是不是这么个叫法&#xff0c;废话不多说。 背景&#xff1a;威联通container station安装了nextcloud和lucky&#xff0c;lucky进行的域名解析和反代 先在想安装的路径、数据存储路径、数据库路径等新建文件夹。再新建…

华为OD机试真题——信道分配(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

比亚迪“双剑”电池获中汽中心权威认证,堪称“移动安全堡垒”。

在新能源汽车发展中&#xff0c;电池安全是重中之重。比亚迪的刀片电池与闪充刀片电池提前通过电池新国标全项检测&#xff0c;获中汽中心权威认证&#xff0c;堪称“移动安全堡垒”。 传统电池极端条件下易热失控&#xff0c;而刀片电池独特长条形设计&#xff0c;似刀片般&am…

【mysql】mysql的高级函数、高级用法

mysql是最常用的数据库之一&#xff0c;常见的函数用法大家应该都很熟悉&#xff0c;本文主要例举一些相对出现频率比较少的高级用法 (注&#xff1a;需注意mysql版本&#xff0c;大部分高级特性都是mysql8才有的) 多值索引与虚拟列 主要是解决字符串索引问题&#xff0c;光说…

【平面波导外腔激光器专题系列】用于光纤传感的低噪声PLC外腔窄线宽激光器

----翻译自Mazin Alalusi等人的文章 摘要 高性价比的 1550 nm DWDM平面外腔 &#xff08;PLANEX&#xff09; 激光器是干涉测量、布里渊、LIDAR 和其他光传感应用的最佳选择。其线宽<3kHz、低相位/频率噪声和极低的RIN。 简介 高性能光纤分布式传感技术是在过去几年中开发…

Pytorch里面多任务Loss是加起来还是分别backward? | Pytorch | 深度学习

当你在深度学习中进入“多任务学习(Multi-task Learning)”的领域,第一道关卡可能不是设计网络结构,也不是准备数据集,而是:多个Loss到底是加起来一起backward,还是分别backward? 这个问题看似简单,却涉及PyTorch计算图的构建逻辑、自动求导机制、内存管理、任务耦合…

一种比较精简的协议

链接地址为&#xff1a;ctLink: 一个比较精简的支持C/C的嵌入式通信的中间协议。 本文采用的协议格式如下 *帧头 uint8_t 起始字节&#xff1a;0XAF\ *协议版本 uint8_t 使用的协议版本号&#xff1a;当前为0X01\ *负载长度 uint8_t 数据段内容长…

网络常识:网线和光纤的区别

网络常识&#xff1a;网线和光纤的区别 一. 介绍二. 网线2.1 什么是网线&#xff1f;2.2 网线的主要类别2.3 网线的优势2.4 网线的劣势 三. 光纤3.1 什么是光纤&#xff1f;3.2 光纤的主要类别3.3 光纤的优势3.4 光纤的劣势 四. 网线 vs 光纤&#xff1a;谁更适合你&#xff1f…

OpenCV CUDA模块图像过滤------创建一个 Scharr 滤波器函数createScharrFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于创建一个 Scharr 滤波器&#xff08;基于 CUDA 加速&#xff09;&#xff0c;用于图像的一阶导数计算。它常用于边缘检测任务中&#…

html css js网页制作成品——HTML+CSS+js醇香咖啡屋网页设计(5页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

brep2seq 源码笔记2

数学公式是什么def forward(self, noise_1, noise_2, real_z_pNone): if(real_z_p): z_p_ self.downsample(real_z_p) input_2 z_p_ noise_2 z_f self.gen_z_f(input_2) output real_z_p z_f else: …

UE5 蓝图,隐藏一个Actor,同时隐藏它的所有子物体

直接用actor.sethideningame是不行的 要先找到根组件&#xff0c;这样就有覆盖子物体的选项了

人工智能AI之机器学习基石系列 第 2 篇:数据为王——机器学习的燃料与预处理

专栏系列&#xff1a;《人工智能AI之机器学习基石》② 高质量的数据是驱动机器学习模型的强大燃料 &#x1f680; 引言&#xff1a;无米之炊与数据的重要性 在上一篇文章《什么是机器学习&#xff1f;——开启智能之门》中&#xff0c;我们一起揭开了机器学习的神秘面纱&…

代码随想录算法训练营 Day58 图论Ⅷ 拓扑排序 Dijkstra

图论 题目 117. 软件构建 拓扑排序&#xff1a;给出一个有向图&#xff0c;把这个有向图转成线性的排序就叫拓扑排序。 当然拓扑排序也要检测这个有向图是否有环&#xff0c;即存在循环依赖的情况&#xff0c;因为这种情况是不能做线性排序的。所以拓扑排序也是图论中判断有向…

实现单例模式的6种方法(Python)

目录 一. 基于模块的实现(简单&#xff0c;易用) 二. 重新创建时报错(不好用) 三. 只靠方法获取实例(不好用) 四. 类装饰器 五. 重写__new__方法 六. 元类 七. 总结 单例模式&#xff08;Singleton Pattern&#xff09;是一种设计模式&#xff0c;其核心目标是确保一个类…

深度学习优化器相关问题

问题汇总 各类优化器SGDMomentumNesterovAdagardAdadeltaRMSpropAdam优化器 为什么Adam不一定最优而SGD最优的深度网络中loss除以10和学习率除以10等价吗L1,L2正则化是如何让模型变得稀疏的&#xff0c;正则化的原理L1不可导的时候该怎么办梯度消失和梯度爆炸什么原因&#xff…

【免费】【无需登录/关注】度分秒转换在线工具

UVE Toolbox 功能概述 这是一个用于地理坐标转换的在线工具&#xff0c;支持两种转换模式&#xff1a; 十进制度 → 度分秒 度分秒 → 十进制度 使用方法 十进制度转度分秒 在"经度"输入框中输入十进制度格式的经度值&#xff08;例如&#xff1a;121.46694&am…

常见的垃圾回收算法原理及其模拟实现

1.标记 - 清除&#xff08;Mark - Sweep&#xff09;算法&#xff1a; 这是一种基础的垃圾回收算法。首先标记所有可达的对象&#xff0c;然后清除未被标记的对象。 缺点是会产生内存碎片。 原理&#xff1a; 如下图分配一段内存&#xff0c;假设已经存储上数据了 标记所有…