终于把Java包装类型的自动装箱搞明白了

简介: 终于把Java包装类型的自动装箱搞明白了
1 什么是包装类型


Java提供了8种基本数据类型及对应的8种包装数据类型。Java是一种面向对象编程的高级语言,所以包装类型正是为了解决基本数据类型无法面向对象编程所提供的。


2 下面是基本数据类型与对应的包装类型。


基本数据类型 包装类型
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double


3 包装类应用场景


(1)集合类泛型只能是包装类;
(2)成员变量不能有默认值;

private int status;


基本数据类型的成员变量都有默认值,如以上代码 status 默认值为 0,如果定义中 0 代表失败,那样就会有问题,这样只能使用包装类 Integer,它的默认值为 null,所以就不会有默认值影响。


(3)方法参数允许定义空值;

private static void test1(int status){
    System.out.println(status);
}


看以上代码,方法参数定义的是基本数据类型 int,所以必须得传一个数字过来,不能传 null,很多场合我们希望是能传递 null 的,所以这种场合用包装类比较合适。


4 自动装箱、拆箱


Java 5 增加了自动装箱、拆箱机制,提供基本数据类型和包装类型的相互转换操作。


5 自动装箱


自动装箱即自动将基本数据类型转换成包装类型,在 Java 5 之前,要将基本数据类型转换成包装类型只能这样做,看下面的代码。


Integer i1 = new Integer(8);
Integer i2 = Integer.valueOf(8);
// 自动装箱
Integer i3 = 8;


以上3种都可以进行转换,但在Java5之前第3种方法是编译失败的,第3种方法也正是现在的自动装箱功能。另外,第一种构造器方法也不推荐使用了,已经标为废弃了。


其实自动装箱的原理就是调用包装类的 valueOf 方法,如第 2 个方法中的 Integer.valueOf 方法。


需要注意的是,关于 Integer,-128 ~ 127 会有缓存,对比这个范围的值的对象是一个坑。通过查看源码,即可看到使用缓存,如下图:



网络异常,图片无法展示
|


Integer自动装箱使用缓存


另外,通过在测试代码中进行断点调试,观察包装类型的地址值,也可以观察到是否使用缓存。如下图所示:



网络异常,图片无法展示
|


Integer自动装箱使用缓存demo测试

相比于包装类Integer使用缓存进行提高性能,包装类Boolean由于值只有两种就相对简单很多,它是通过不可变的类成员变量进行提前初始化。源码如下图:



网络异常,图片无法展示
|


Boolean源码


当boolean类型进行自动装箱时,用的都是提前初始化完成的静态不可变的成员变量,这点通过代码断点调试,观察变量地址值,即可发现端倪,如下图:



网络异常,图片无法展示
|


image.png


6 自动拆箱


自动拆箱即自动将包装类型转换成基本数据类型,与自动装箱相反,有装就有拆,很好理解。


// 自动拆箱
int i4 = i3;
int i5 = i3.intValue();


继续上面的例子,把 i3 赋值给 i4 就是实现的自动拆箱功能,自动装箱的原理就是调用包装类的 xxValue 方法,如 i5 中的 Integer 的 intValue 方法。

自动装箱、拆箱不只是体现在以上的例子,在方法接收参数、对象设置参数时都能自动装箱拆箱。


7 文章缘起


之所以会整理出来这篇文章,主要就是源于下面的代码,我想当然地把Boolean类型看成了引用类型,故而认为此处打印输出的值,应该为false。后面经过查找资料,分析源码,才明白具体原因。



网络异常,图片无法展示
|


缘起的demo代码


包装类的存在主要是为了解决基本类型在使用过程中的一些不便,这点通过包装类的应用场景也可以看出来。而包装类在解决基本类型的不便的同时又在尽可能减少资源空间占用,所以用了缓存及其他不可变的静态成员变量等方式,这点是很值得借鉴学习的。

通过上面的测试代码,也可以看出来包装类在解决基本类型的不便的同时还具备基本类型的用法,所以上面的变量如果直接理解成基本类型的话,就完全可以理解了,其实那就是基本类型,只是多了一个自动装箱而已。



相关文章
|
2天前
|
存储 Java 开发者
Java 中 Set 类型的使用方法
【10月更文挑战第30天】Java中的`Set`类型提供了丰富的操作方法来处理不重复的元素集合,开发者可以根据具体的需求选择合适的`Set`实现类,并灵活运用各种方法来实现对集合的操作和处理。
|
2天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
8 2
|
24天前
|
Java 编译器
Java“返回类型为 void 的方法不能返回一个值”解决
在 Java 中,如果一个方法的返回类型被声明为 void,那么该方法不应该包含返回值的语句。如果尝试从这样的方法中返回一个值,编译器将报错。解决办法是移除返回值语句或更改方法的返回类型。
|
26天前
|
设计模式 Java
Java“不能转换的类型”解决
在Java编程中,“不能转换的类型”错误通常出现在尝试将一个对象强制转换为不兼容的类型时。解决此问题的方法包括确保类型间存在继承关系、使用泛型或适当的设计模式来避免不安全的类型转换。
|
23天前
|
Java
Java 中锁的主要类型
【10月更文挑战第10天】
|
30天前
|
安全 Java
Java“不兼容类型” 错误怎么查找解决
在 Java 中遇到“不兼容类型”错误时,首先理解错误信息,它表明试图将一种类型赋给不兼容的类型。检查代码中类型不匹配的赋值、方法调用参数类型不匹配、表达式类型不兼容及泛型类型不匹配等问题。解决方法包括进行类型转换、修改代码逻辑、检查方法参数和返回类型以及处理泛型类型不匹配。通过这些步骤,可以有效解决“不兼容类型”错误,确保代码类型兼容性良好。
|
2月前
|
存储 Java Windows
java基础(9)数据类型中的char类型以及涉及到的转义字符
Java中的char类型可以存储一个中文字符,因为它占用两个字节。转义字符允许在代码中使用特殊字符,例如`\n`表示换行,`\t`表示制表符,`\\`表示反斜杠,`\'`表示单引号,`\"`表示双引号。可以使用`\u`后跟Unicode编码来表示特定的字符。
47 2
java基础(9)数据类型中的char类型以及涉及到的转义字符
|
29天前
|
Java 程序员 编译器
Java中的异常类型
Java中的异常类型
21 3
|
29天前
|
Java 开发者
Java“类 Y 中的方法 X 不能应用于给定类型”解决
在Java中遇到“类Y中的方法X无法应用于给定类型”的错误时,通常是因为方法调用时的参数类型与定义不符。解决此问题需检查方法签名,确保传递的参数类型正确无误,或使用显式类型转换以匹配方法所需的参数类型。这种错误提示帮助开发者及时修正类型不匹配的问题。
|
1月前
|
Java 程序员 编译器
Java中的异常类型
Java中的异常类型
20 3