包装类、自动装箱、自动拆箱是什么?有哪些注意点?

1、包装类

Java中的数据类型总体上分为基本数据类型和引用数据类型。引用类型的数据可以通过对象的属性和方法来进行操作,但对于基本数据类型的数据,我们能不能像操作对象那样来操作呢?为了实现这个目标,Java为8种基本数据类型分别设计了对应的类,这就是包装类 (Wrapper Classes,外覆类,数据类型类)。因为这些包装类都是引用类型,所以我们就可以方便地操作这些数据的属性和方法了。包装类的设计主要是为了配合Java 5之后出现的泛型,在泛型的使用中,基本数据类型和泛型不能混用。比如我们想使用ArrayList、HashMap等集合时,这些集合都需要指明集合中数据的泛型,而这些集合容器的泛型都必须是Object类型,像int、double这些基本类型是不允许使用的,所以就需要包装类。包装类的类名,就是把基本类型的首字母变成大写,除了Integer和Character特殊一点。另外,Byte、Short、Integer、Long、Float、Double这六个类,都是Number的子类,它们具有一些共同的类型转换方法,方便我们进行类型之间的转换。具体如下图所示:

  • 基本数据类型的数据存储在栈中,而包装类型的对象存储在堆中,因此基本数据类型的操作比包装类型的操作更加高效。建议尽量使用基本数据类型,而不是对应的包装类型。

2、自动装箱

**自动装箱是指 Java 编译器把基本数据类型自动转换为对应的包装类。**例如,将 int 类型转换为 Integer 类型,将 double 类型转换为 Double 类型等。如果转换以相反的方式进行,则称为开箱。以下代码就是自动装箱的例子。

java 复制代码
Character ch = 'a';

List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
    li.add(i);  // 实际实现的是:li.add(Integer.valueOf(i));

3、自动拆箱

**自动拆箱是指 Java 编译器把包装类自动转换为对应的基本数据类型。**例如,将 Integer 类型转换为 int类型,将 Double 类型转换为double 类型等。以下代码就是自动拆箱的例子。

java 复制代码
public static int sumEven(List<Integer> li) {
    int sum = 0;
    for (Integer i: li)
        if (i % 2 == 0)  //自动拆箱
            sum += i;  //自动拆箱
        return sum;
}
//上面代码实际实现的是
public static int sumEven(List<Integer> li) {
    int sum = 0;
    for (Integer i : li)
        if (i.intValue() % 2 == 0) //手动拆箱操作
            sum += i.intValue();  //手动拆箱操作
        return sum;
}

4、字符串与自动装箱

如果你在拼接字符串时涉及到数字或其他非字符串对象,那么Java会使用自动装箱将这些对象转换为字符串。所以在字符串拼接时,建议使用 StringBuilder 或 StringBuffer,而不是字符串连接符 "+",以避免自动装箱导致的开销。

java 复制代码
int a = 10;  
String b = "World";  
String c = a + b; // 自动装箱:这里的a会被自动转换为它的字符串表示形式"10"

5、注意点

自动装箱和拆箱对程序性能会有一定的影响,但也要具体情况具体分析。优化应该是有目的的,而不是盲目的。在大多数情况下,自动装箱和拆箱对程序性能的影响并不大。只有在你确定这是性能瓶颈时,才应该专注于优化这部分代码。其他情况下,稍加注意即可:

  • 使用包装类型的目的明确:尽量只在需要的时候使用包装类型,并明确它们的使用目的。尽量避免在不需要的情况下使用它们。
  • 使用原始类型:在已知变量类型的情况下,使用原始类型通常比使用包装类型更有效。
  • 避免不必要的自动装箱:尽量避免在循环或大量计算中自动装箱。如果可能,手动进行装箱操作,以减少不必要的开销。
  • 避免过度优化:在大多数情况下,自动装箱和拆箱对程序性能的影响并不大。过度优化可能会使代码变得难以阅读和维护。
  • 使用StringBuilder进行字符串拼接:当需要大量拼接字符串时,使用StringBuilder或StringBuffer通常比使用"+"运算符更高效。
  • 进行性能测试和分析:使用Java的性能分析工具(如JProfiler、VisualVM等)来监测和分析程序性能。通过这种方式,你可以确定自动装箱和其他开销较大的操作对程序性能的具体影响。
相关推荐
LuckyLay16 分钟前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring
向阳121829 分钟前
Dubbo负载均衡
java·运维·负载均衡·dubbo
Gu Gu Study38 分钟前
【用Java学习数据结构系列】泛型上界与通配符上界
java·开发语言
WaaTong1 小时前
《重学Java设计模式》之 原型模式
java·设计模式·原型模式
m0_743048441 小时前
初识Java EE和Spring Boot
java·java-ee
AskHarries1 小时前
Java字节码增强库ByteBuddy
java·后端
小灰灰__1 小时前
IDEA加载通义灵码插件及使用指南
java·ide·intellij-idea
夜雨翦春韭1 小时前
Java中的动态代理
java·开发语言·aop·动态代理
程序媛小果2 小时前
基于java+SpringBoot+Vue的宠物咖啡馆平台设计与实现
java·vue.js·spring boot
追风林2 小时前
mac m1 docker本地部署canal 监听mysql的binglog日志
java·docker·mac