首页 > 编程语言 >基础巩固、探寻Java装箱和拆箱的奥妙!

基础巩固、探寻Java装箱和拆箱的奥妙!

时间:2023-04-24 21:04:07浏览次数:43  
标签:拆箱 Java 包装 数据类型 类型 装箱

前言

  今天在逛某知名论坛的时候,看到一篇"请不要使用包装类型,避免造成性能损失"的文章。一下子就吸引了我的注意。大意就是,能用基本数据类型就尽量用基本数据类型,因为包装类型自动拆箱、装箱会带来性能损失尤其是循环使用时会大量创建对象。所以今天聊一下,Java的装箱和拆箱。

什么是装箱和拆箱?

  Java中的装箱(boxing)和拆箱(unboxing)是指将基本数据类型与其对应的包装类之间进行转换的过程。

装箱

  装箱是将基本数据类型转换为其对应的包装类,例如将int类型转换为Integer类型。这个过程是通过自动装箱(autoboxing)或手动装箱(manual boxing)完成的。自动装箱是指Java编译器自动将基本类型转换为包装类型,而手动装箱则是通过调用包装类的构造函数来完成。

拆箱

  拆箱是将包装类转换为其对应的基本数据类型,例如将Integer类型转换为int类型。这个过程也是通过自动拆箱(autounboxing)或手动拆箱(manual unboxing)完成的。自动拆箱是指Java编译器自动将包装类型转换为基本类型,而手动拆箱则是通过调用包装类的xxxValue()方法来完成。

为啥要包装类型?

  在日常使用的时候,感觉用基本类型还是包装类型貌似没啥区别。如果去掉包装类型,那就不需要装箱和拆箱了。也就避免了性能损失。貌似很完美呀。

  如果你是这样想就,大错特错了。java中有基本数据类型和包装类型,这是为了满足不同需求的设计。java大佬们肯定不会做这样的无用功的,使用包装类型的主要原因包括:

  • 对象引用:基本类型不是对象,无法使用对象引用,而包装类型是对象,可以通过引用来操作。

  • 泛型:泛型不能使用基本数据类型,必须使用包装类型。如,使用List<Integer>来存储一组整数,而不是使用List<int>

  • null值:基本类型不能为null,而包装类型可以为null。

  • 类型转换:包装类型提供了许多类型转换方法,例如将字符串转换为整数或浮点数等,这些方法非常方便。

  • 方法重载:方法重载可以使用不同的参数类型,但是基本数据类型和其对应的包装类型在方法中被认为是相同的类型,因此可以在方法中使用它们进行重载。

  尽管基本数据类型在Java中非常有用,但是包装类型提供了更多的功能和灵活性,因此在某些情况下使用包装类型会更为方便和实用。所以就有了装箱和拆箱的过程。

装箱和拆箱的进化过程

  在Java 1.4及之前,装箱和拆箱需要手动进行,即需要使用对应的构造函数或方法来完成。例如,要将int类型的变量x装箱成Integer类型,可以使用以下代码:

int x = 10;
Integer y = new Integer(x);  // 手动装箱

要将Integer类型的变量y拆箱成int类型,可以使用以下代码:

Integer y = new Integer(10);
int x = y.intValue();  // 手动拆箱

  这种方式比较繁琐,也容易出错。因此,从Java 5开始,引入了自动装箱和拆箱机制。这意味着我们可以直接将基本数据类型赋值给对应的封装类型变量,或将封装类型变量赋值给对应的基本数据类型变量,编译器会自动完成转换。例如:

int x = 10;
Integer y = x;  // 自动装箱
int z = y;  // 自动拆箱

  从Java 9开始,引入了一种新的装箱方式,称为“紧凑型装箱”(Compact Number Box),它能够更高效地存储小范围内的数值。紧凑型装箱只适用于byte、short和int类型的封装类型,这些类型的取值范围都比较小(如byte的取值范围为-128到127),因此可以使用一个byte或short类型的变量来存储它们的值,而无需使用一个整型变量。

到底该如何选择呢?

  基本类型是Java语言的基础,可以直接存储在栈中,具有较高的执行效率和较小的内存占用。包装类型是把基本类型封装起来的对象,可以在堆中存储,可以进行各种面向对象的操作。所以在选择使用基本类型还是包装类型时,可以考虑以下几个因素:

  1. 执行效率:基本类型具有较高的执行效率,尤其是在大量计算的情况下,使用基本类型可以明显提高程序的执行速度。

  2. 内存占用:基本类型在栈中存储,占用的内存较小,而包装类型在堆中存储,占用的内存较大。

  3. 对象操作:如果需要进行面向对象的操作,例如通过equals()方法比较两个变量的值,或者将基本类型转换为字符串,就需要使用包装类型。

  4. 空值处理:基本类型不能表示空值,而包装类型可以用null表示空值,因此在需要处理空值的情况下,需要使用包装类型。

总结

  Java中的装箱和拆箱技术经历了从手动到自动、从普通到紧凑型的演进,这使得我们能够更方便地操作基本数据类型和封装类型之间的转换。虽然更加方便, 但是在实际开发中,还是需要根据具体的使用场景进行选择。

结尾

  如果觉得对你有帮助,可以多多评论,多多点赞哦,也可以到我的主页看看,说不定有你喜欢的文章,也可以随手点个关注哦,谢谢。

  我是不一样的科技宅,每天进步一点点,体验不一样的生活。我们下期见!

标签:拆箱,Java,包装,数据类型,类型,装箱
From: https://blog.51cto.com/u_11446735/6221852

相关文章

  • java反序列化(五) JNDI注入
    JNDI注入前置知识JNDIJNDI(JavaNamingandDirectoryInterface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。可以通过字符串来锁定一个对象JNDI支持的服务主要有以下几种:RMI(JAVA远程方法调用)LDAP(轻量级目录访问协......
  • Java-基础篇【数组、方法、面向对象基础.】
    1:数组引用类型,不是基本数据类型2:静态初始化数组111 ......
  • Java中缓存区的基本使用
    前言缓存区是一种内存空间,在计算机程序中被广泛使用来优化I/O操作的效率。在文件I/O操作中,缓存区用于缓存将要写入磁盘或读取到内存中的数据。这样可减少对磁盘的访问次数,提高I/O操作的效率。本文将介绍缓存区的基本使用以及一些注意点,并提供一个实例来演示如何将一个jpg图片复制......
  • java执行linux语句
    publicclassCommandUtil{/***在指定路径下执行一条命令,不能执行cd之类的命令**@paramcommand要执行的Linux命令*@paramdir目标路径,在该路径执行上述Linux命令*@return命令执行后显示的结果*@throwsIOException*/......
  • Java中Runnable和Callable的区别 Runnable接口
    Callable接口从Java1.0开始,它是java.lang包的一部分从Java1.5开始,它是java.util.concurrent包的一部分。Runnable接口不能返回计算的结果。Callable接口可以返回一个任务的并行处理的结果。Runnable接口不能抛出一个有检查的异常。Callable接口可以抛出一个有检查的异常。......
  • java反序列化(五) JNDI注入
    JNDI注入前置知识JNDIJNDI(JavaNamingandDirectoryInterface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口。可以通过字符串来锁定一个对象JNDI支持的服务主要有以下几种:RMI(JAVA远程方法调用)LDAP(轻量级目录访问协......
  • Java中null和“”的区别
    null和空字符串('')虽然都是没有任何内容,但是null却输出空指针异常,因为堆内存中根本就没有这个东西。他们的区别可相当大,虽然都是没有信息,但是null代表堆内存中根本没有这个东西,这个对象不存在,怎么执行indexof操作?空字符串虽然没有信息,但是是有内存空间的,所以null与空字符串主要......
  • springboot mybatis 动态调用oracle存储过程,通过存储过程名称,就能动态调用存储过程、j
    由于在开发业务时,可能同时调用的存储过程不知道参数,但是参数从界面、或已经存储在数据库的获取,所以就不希望手动写存储过程的参数,通过简化的调用。能不能写个动态的业务,只输入存储过程名称,自动获取存储过程参数,并且参数的数据从前台传递过来,这个就通用了。只写一个通用方法,就可以......
  • Java 依赖注入(DI)
    只要做过Java一段时间,基本上都会遇到这个问题。DependencyInjection(DI)中文称之为依赖注入。都说了Spring的关键部分就是DependencyInjection(DI),但是什么是依赖,为什么要注入,基本上没怎么找到使用简单文字说明的本文尝试用土话把这个问题说明白。这里有2个概念,依赖和注入。......
  • java -- 注解
    注解注解概述定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。作用分类:编写文档:通过代码里标识的注解生成......