当前位置: 首页 > article >正文

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

自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。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 propertyint 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_VALUEh = 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));//trueInteger in3 = 1234;Integer in4 = 1234;System. out .println(in3 == in4);//false 因为 1234 不在缓存范围内System. out .println(in3.equals(in4));//true

执行后的结果: 

 

 如下是Test3的内存分析:

http://www.lryc.cn/news/2387753.html

相关文章:

  • java-jdk8新特性Stream流
  • 大语言模型 21 - MCP 自动操作 Figma+Cursor 实现将原型转换为代码
  • QNAP NEXTCLOUD 域名访问
  • Spring MVC深度解析:控制器与视图解析及RESTful API设计最佳实践
  • 华为OD机试真题——信道分配(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
  • 比亚迪“双剑”电池获中汽中心权威认证,堪称“移动安全堡垒”。
  • 【mysql】mysql的高级函数、高级用法
  • 了解一下C#的SortedSet
  • 【平面波导外腔激光器专题系列】用于光纤传感的低噪声PLC外腔窄线宽激光器
  • Pytorch里面多任务Loss是加起来还是分别backward? | Pytorch | 深度学习
  • K8S Pod调度方法实例
  • 【mindspore系列】- 算子源码分析
  • 学习日记-day17-5.27
  • 一种比较精简的协议
  • 网络常识:网线和光纤的区别
  • OpenCV CUDA模块图像过滤------创建一个 Scharr 滤波器函数createScharrFilter()
  • html css js网页制作成品——HTML+CSS+js醇香咖啡屋网页设计(5页)附源码
  • [特殊字符] 构建高内聚低耦合的接口架构:从数据校验到后置通知的分层实践
  • brep2seq 源码笔记2
  • UE5 蓝图,隐藏一个Actor,同时隐藏它的所有子物体
  • 人工智能AI之机器学习基石系列 第 2 篇:数据为王——机器学习的燃料与预处理
  • 代码随想录算法训练营 Day58 图论Ⅷ 拓扑排序 Dijkstra
  • 实现单例模式的6种方法(Python)
  • 基于 STM32 的智慧农业温室控制系统设计与实现
  • 深度学习优化器相关问题
  • 【免费】【无需登录/关注】度分秒转换在线工具
  • 常见的垃圾回收算法原理及其模拟实现
  • fpga-编程线性序列机和状态机
  • 力扣面试150题--完全二叉树的节点个数
  • Qt 多线程环境下的全局变量管理与密码安全