基本数据类型和包装类型的区别、缓存池、自动拆箱装箱(面试题)

news2024/12/26 11:53:32

目录

1. 八种基本类型及对应包装类型

2. 基本类型和包装类型 区别

3. 自动拆箱装箱

3.1 自动装箱

3.2 自动拆箱

3.3 缓存池

4. 高频面试案例分析


1. 八种基本类型及对应包装类型

基本数据类型类型描述范围(指数形式)位数包装类型
byte整型(有符号)-2 ^ 7 ~2 ^ 7 -11字节= 8bitByte
short整型(有符号)-2 ^ 15 ~2 ^ 15 -12字节=16bitShort
int整型(有符号)-2 ^ 31 ~2 ^ 31 -14字节= 32bitInteger
long整型(有符号)-2 ^ 63 ~2 ^ 63 -18字节= 64bitLong
float浮点型1.401298e-45 ~ 3.402823e+38(绝对值)4字节=32bitFloat
double浮点型4.9000000e-324 ~ 1.797693e+308(绝对值)8字节=64bitDouble
char字符型‘\u0000’~’\uFFFF’2字节=16bitCharacter
boolean布尔型只有两个值:true 或 false1字节= 8bitBoolean

2. 基本类型和包装类型 区别

  • 1.性能

基本类型:占用内存小,效率高,适合频繁使用的简单操作。
包装类型:因为是对象,涉及内存分配和垃圾回收,性能相对较低。

  • 2. 存储位置

基本类型:如果是局部变量则保存在栈上面,如果是成员变量则在堆中。
包装类型:保存在堆上(成员变量,在不考虑JIT优化的栈上分配时,都是随着对象一起保存在堆上的)。

基本数据类型:

  • 1、变量名指向具体的数值。
  • 2、基本数据类型存储在栈上。

引用数据类型:

  • 1、变量名指向的是存储对象的内存地址,在栈上。
  • 2、内存地址指向的对象存储在堆上。

  • 3. 初始化方式

基本类型:直接赋值
包装类型:需要采用new的方式创建

  • 4. 比较方式

基本类型:比较用==,直接比较数值。
包装类型:比较时,==比较的是对象的内存地址,而equals()比较的是对象的值。

  • 5. 默认值

基本类型:默认值是0,false 等。
包装类型:默认为null。

3. 自动拆箱装箱

3.1 自动装箱

装箱 :就是将基本数据类型用他们对应的包装类包装起来

Integer i = 10;

我们将上述代码反编译即得到:

Integer i = Integer.valueOf(10);

查看源码可知:

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

在Integer的valueof(int i)中,我们传递进去的参数是基本数据类型int型,在函数内部如上所示利用了Integer内部的一个私有静态类IntegerCache,该类静态初始化了一个包含了Integer.IntegerCache.lowjava.lang.Integer.IntegerCache.high的Integer数组。其中java.lang.Integer.IntegerCache.high的取值范围在[127~Integer.MAX_VALUE - (-low) -1]之间。

在该区间内所有的Integer.valueOf(int)函数返回的对象,是根据int值计算的偏移量,从数组Integer.IntegerCache.cache中获取,返回一个Integer对象。如果不在[IntegerCache.low~IntegerCache.high)之间,就会在JVM中分配内存new一个新的Integer对象。

因此,我们可以看出来装箱的时候其实就是自动调用了Integer的valueOf(int)方法

3.2 自动拆箱

拆箱就是将包装类型转换为基本数据类型

如下:

Integer i = 10;//装箱
int n = i;   //拆箱

反编译得到:

Integer i = Integer.valueOf(10);
int n = i.intValue();

查看源码:

private final int value;
public int intValue() {
    return value;
}

可以看出,在拆箱的时候调用了Integer对象的intValue()方法。包装类在装箱时,将我们传入的int型参数value保存起来且私有不能被改变,在拆箱时利用intValue()方法返回int型的value值。

因此总结一下装箱和拆箱的实现过程就是:

装箱过程是通过调用包装类的valueOf方法实现的,而拆箱过程是通过调用包装类的 xxxValue方法实现的。(xxx代表对应的基本数据类型)。

注意:我们要了解的是,频繁的装箱拆箱的话,会增加内存的消耗,影响性能

  

3.3 缓存池

java中有6个缓存池,基本数据类型的包装类除了 Float 和 Double 之外,其他六个包装器类(Byte、Short、Integer、Long、Character、Boolean)都有常量缓存池

  • Byte:-128~127,也就是所有的 byte 值
  • Short:-128~127
  • Long:-128~127
  • Character:\u0000 - \u007F
  • Boolean:true 和 false

下面详细说一下java中 Integer缓存池

Java的Integer缓存池(IntegerCache)是为了提升性能和节省内存。根据实践发现大部分的数据操作都集中在值比较小的范围,因此缓存这些对象可以减少内存分配和垃圾回收的负担,提升性能

拿 Integer 来举例子

Integer 类内部中内置了 256 个 Integer 类型的缓存数据,当使用的数据范围在 -128~127 之间时会直接返回常量池中数据的引用,而不是创建对象超过这个范围时会创建新的对象。

  • new Integer(100) 每次都会新建一个对象;
  • Integer.valueOf(100) 会使用缓存池中的对象,多次调用只会取同⼀一个对象的引用。

原理:

Java 在自动装箱时,对于值在-128到127之间的int类型,会直接返回一个已经缓存的Integer 对象,而不是创建新的对象。

缓存池的使用场景:

  • 自动装箱(Auto-boxing):当基本类型int转换为包装类Integer时,若数值在缓存范围内,返回缓存对象。

  • 值比较:由于相同范围内的整数使用同一个缓存对象,使用==可以正确比较它们的地址(引用相同),而不需要使用equals()。但是要注意对于超过缓存范围的Integer对象,==比较的是对象引用,而不是数值。要比较数值,应使用equals()方法。

4. 高频面试案例分析

下面这段代码的输出结果是什么呢?

public class Main {
    public static void main(String[] args) {
         
        Integer i1 = 100;
        Integer i2 = 100;
        Integer i3 = 200;
        Integer i4 = 200;

        Integer one=new Integer(100);
        Integer two=new Integer(100);

        Integer z = Integer.valueOf(18);
        Integer k = Integer.valueOf(18);
        System.out.println(z == k);//6

        System.out.println(i1==i2);   //1
        System.out.println(i3==i4);   //2    
        System.out.println(one==two);  //3
        System.out.println(i1==100);   //4
        System.out.println(i1==one);   //5


        

    }

提醒:

1.   ”==“用于比较引用和比较基本数据类型时具有不同的功能,具体如下:

  • 基本数据类型:比较的是他们的值是否相等,比如两个int类型的变量,比较的是变量的值是否一样。
  • 引用数据类型:比较的是引用的地址是否相同,比如说新建了两个User对象,比较的是两个User的地址是否一样。

2. 装箱过程(基本类型转为包装类型)是通过调用包装类的valueOf方法实现的,而拆箱过程(包装类型转为基本类型)是通过调用包装类的 xxxValue方法实现的。(xxx代表对应的基本数据类型);

Integer包装类当使用的数据范围在 -128~127 之间时会直接返回常量池中数据的引用,而不是创建对象超过这个范围时会创建新的对象。

  • new Integer(100) 每次都会新建一个对象;
  • Integer.valueOf(8) 会使用缓存池中的对象,多次调用只会取同⼀一个对象的引用。

解答:

1,true,上面的代码中i1和i2的数值为100,是Integer包装类型且数据范围在 -128~127 之间,因此直接从IntegerCache(Integer缓存池)会直接返回常量池中数据的引用,而不是创建对象,超过这个范围时会创建新的对象。

2,false,这里很多同学容易出错,上面的代码中i3和i4的数值为200,根据IntegerCache私有静态类的源码可以发现,当数值不在[127~Integer.MAX_VALUE - (-low) -1]即[-128,127]之间时,便会创建新的Integer对象。因此这里i3和i4是两个不同对象,因此为false。

3,false,这里就很好理解了,因为new Integer(100);创建了两个不同的对象,==比较的是内存地址。

4,true,这里其实包含两个步骤:① Integer i1 = 100;进行装箱;② i1==100自动进行了拆箱,因此这里是两个基本数据类型进行比较,值必然相同。

i1是一个Integer对象,而100是一个基本类型int的值。在比较Integer对象和基本类型int时,Java会进行自动拆箱,将Integer对象转换成int值进行比较。由于i1实际上是缓存中的对象,它的值是100,所以i1的值(100)和基本类型int的值(100)是相等的,

5,false,i1对象进行了装箱,其是直接从IntegerCache私有静态类的Integer数组中取已经存在的对象。而one是创建了一个新的对象,因此两者的内存地址必然不相同。

6,true,这里调用了valueOf方法 装箱,第一次Integer z = Integer.valueOf(18);会创建 Integer对象值是18(在 -128~127 之间),并且放入Integer缓存池中,第二次Integer k = Integer.valueOf(18);会直接从缓存中返回 值为18的Integer对象的地址值,本质是同一个对象引用,所以z=k,true。

参考:

https://blog.csdn.net/qq_44085437/article/details/124028654

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

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

相关文章

如何在Microsoft Edge中删除已保存的网站密码

目录 前言1. 如何进入Edge的密码管理界面1.1 打开Microsoft Edge的设置菜单1.2 进入个人资料设置1.3 进入密码管理 2. 在Edge中查看和删除已保存的密码2.1 查找需要删除的密码2.2 检查密码安全性2.3 删除特定网站的密码 3. 提升Edge密码管理的安全性3.1 启用Edge的多重身份验证…

Spring Boot框架:电商开发的新趋势

5 系统实现 系统实现部分就是将系统分析&#xff0c;系统设计部分的内容通过编码进行功能实现&#xff0c;以一个实际应用系统的形式展示系统分析与系统设计的结果。前面提到的系统分析&#xff0c;系统设计最主要还是进行功能&#xff0c;系统操作逻辑的设计&#xff0c;也包括…

后端:Aop 面向切面编程

文章目录 1. Aop 初步学习面向切面编程&#xff0c;EnableAspectJAutoProxy2. AOP的核心概念3. 前置通知&#xff08;Before&#xff09;4. 后置通知&#xff08;After&#xff09;5. 返回通知&#xff08;AfterReturning&#xff09;6. 异常通知&#xff08;AfterThrowing&…

三周精通FastAPI:41 部署:FastAPI版本和HTTPS概念

官方文档&#xff1a;https://fastapi.tiangolo.com/zh/deployment/versions/ 关于 FastAPI 版本 FastAPI 已在许多应用程序和系统的生产环境中使用。 并且测试覆盖率保持在100%。 但其开发进度仍在快速推进。 经常添加新功能&#xff0c;定期修复错误&#xff0c;并且代码仍…

Pinpoint(APM)进阶--Pinot指标采集(System Metric/Inspector)

接上文 Pinpoint使用Pinot进行指标数据存储&#xff0c;Pinot流摄入需要Kafka 本文详解Kafka和Pinot的安装部署&#xff0c;以及Pinpoint的指标采集 Pinot 简介 Apache Pinot是一个实时分布式OLAP数据存储&#xff0c;专为低延迟、高吞吐量分析而构建&#xff0c;非常适合面…

ReactPress:重塑内容管理的未来

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎提出宝贵的建议&#xff0c;欢迎一起共建&#xff0c;感谢Star。 ReactPress&#xff1a;重塑内容管理的未来 在当今信息爆炸的时代&#xff0c;一个高效、易用的内容管理系统&#xff0…

uniapp路由与页面跳转详解:API调用与Navigator组件实战

UniApp路由与页面跳转详解&#xff1a;API调用与Navigator组件实战 路由 uniapp页面路由为框架统一管理&#xff0c;开发者需要在page.json里面配置每个路由页面的路径及页面样式。 路由跳转 uniapp有两种页面路由跳转方式&#xff0c;调用API跳转和navigator组件跳转。 调…

35.Redis 7.0简介

2022 年 2 月初&#xff0c;Redis 7.0 迎来了首个候选发布&#xff08;RC&#xff09;版本。这款内存键值数据库迎来了“重大的性能优化”和其它功能改进&#xff0c;性能优化包括降低写入时复制内存的开销、提升内存效率&#xff0c;改进 fsync 来避免大量的磁盘写入和优化延迟…

MySQL技巧之跨服务器数据查询:基础篇-如何获取查询语句中的参数

MySQL技巧之跨服务器数据查询&#xff1a;基础篇-如何获取查询语句中的参数 上一篇已经描述&#xff1a;借用微软的SQL Server ODBC 即可实现MySQL跨服务器间的数据查询。 而且还介绍了如何获得一个在MS SQL Server 可以连接指定实例的MySQL数据库的连接名: MY_ODBC_MYSQL 以…

连续15年霸榜“双11”行业第一,九牧做对了什么?

文 | 螳螂观察&#xff08;TanglangFin&#xff09; 作者 | 余一 随着“双十一”的落幕&#xff0c;各类销售榜单再次成为热门话题。 天猫“双11”全周期589个品牌成交额破亿&#xff0c;其中苹果、海尔、美的、小米、九牧等45个品牌成交额突破10亿。 值得注意的是在绝大多…

【网页设计】HTML5 和 CSS3 提高

目标 能够说出 3~5 个 HTML5 新增布局和表单标签能够说出 CSS3 的新增特性有哪些 1. HTML5 的新特性 注&#xff1a;该部分所有内容可参考菜鸟教程菜鸟教程 - 学的不仅是技术&#xff0c;更是梦想&#xff01; (runoob.com) HTML5 的新增特性主要是针对于以前的不足&#xf…

Linux手动安装nginx

本次以安装nginx-1.12.2为例 1、首先说明一下,安装nginx之前需要安装如下素材: 2、开始安装 第一步,安装依赖yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel第二步,下载并安装nginx安装包(nginx官网:http://nginx.org/)# 下载 wget http://nginx…

基于springboot+vue实现的大型超市数据处理系统 (源码+L文+ppt)4-015

第4章 系统设计 本章主要讲述的是大型超市数据处理系统的设计开发结构&#xff0c;简单介绍了开发流程与数据库设计的原则以及数据表的关系结构图&#xff0c;并且详细的展示了数据表的内部结构信息与属性。 图4-2 大型超市数据处理系统总体结构图 4.4 数据表信息&#xff…

游戏引擎学习第七天

视频参考:https://www.bilibili.com/video/BV1QFmhYcE69 ERROR_DEVICE_NOT_CONNECTED 是一个错误代码&#xff0c;通常在调用 XInputGetState 或 XInputSetState 函数时返回&#xff0c;表示指定的设备未连接。通常会出现以下几种情况&#xff1a; 未连接控制器&#xff1a;如…

IEC60870-5-104 协议源码架构详细分析

IEC60870-5-104 协议源码架构 前言一、资源三、目录层级一二、目录层级二config/lib60870_config.hdependencies/READMEexamplesCMakeLists.txtcs101_master_balancedcs104_client_asyncmulti_client_servertls_clienttls_server说明 make这些文件的作用是否需要导入这些文件&a…

全面介绍软件安全测试分类,安全测试方法、安全防护技术、安全测试流程

一、软件系统设计开发运行安全 1、注重OpenSource组件安全检查和版本更新&#xff08;black duck&#xff09; 现在很多云、云服务器都是由开源的组件去搭成的&#xff0c;对于OpenSource组件应该去做一些安全检查和版本更新&#xff0c;尤其是版本管理&#xff0c;定期对在运…

Cent OS-7的Apache服务配置

WWW是什么&#xff1f; WWW&#xff08;World Wide Web&#xff0c;万维网&#xff09;是一个全球性的信息空间&#xff0c;其中的文档和其他资源通过URL标识&#xff0c;并通过HTTP或其他协议访问。万维网是互联网的一个重要组成部分&#xff0c;但它并不是互联网的全部。互联…

遗传算法与深度学习实战(23)——利用遗传算法优化深度学习模型

遗传算法与深度学习实战&#xff08;23&#xff09;——利用遗传算法优化深度学习模型 0. 前言1. 神经进化2. 使用遗传算法作为深度学习优化器小结系列链接 0. 前言 神经进化涵盖了所有用于改进深度学习的进化算法。更具体地说&#xff0c;神经进化用来定义应用于深度学习的特…

Kubernetes 核心组件调度器(Scheduler)

文章目录 一&#xff0c;调度约束1.Kubernetes的基本构建块和最小可调度单元pod创建过程&#xff08;工作机制&#xff0c;重点&#xff09;1.1list-watch 组件List-Watch 的优点List-Watch 的应用场景List-Watch 的挑战与优化 2.调度过程(重点)2.1调度过程&#xff1a;2.2Kube…

STM32WB55RG开发(3)----生成 BLE 程序连接手机APP

STM32WB55RG开发----3.生成 BLE 程序连接手机APP 概述硬件准备视频教学样品申请源码下载参考程序选择芯片型号配置时钟源配置时钟树RTC时钟配置RF wakeup时钟配置查看开启STM32_WPAN条件配置HSEM配置IPCC配置RTC启动RF开启蓝牙设置工程信息工程文件设置结果演示 概述 本项目旨…