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

目录

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 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() {}
}

在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);//6System.out.println(i1==i2);   //1System.out.println(i3==i4);   //2    System.out.println(one==two);  //3System.out.println(i1==100);   //4System.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.mzph.cn/news/886390.shtml

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

相关文章

Python酷库之旅-第三方库Pandas(221)

目录 一、用法精讲 1036、pandas.DatetimeIndex.to_pydatetime方法 1036-1、语法 1036-2、参数 1036-3、功能 1036-4、返回值 1036-5、说明 1036-6、用法 1036-6-1、数据准备 1036-6-2、代码示例 1036-6-3、结果输出 1037、pandas.DatetimeIndex.to_series方法 10…

基于SpringBoot网上超市的设计与实现录像

基于SpringBoot网上超市的设计与实现录像 SpringBoot网上超市的设计与实现录像

【vmware+ubuntu16.04】vm虚拟机及镜像安装-tools安装包弹不出来问题

学习机器人这门课需要下载虚拟机&#xff0c;做一下记录 首先我下载的是vm虚拟机16&#xff0c; 下载版本可参考该文章课堂上我下载 的镜像是16.04&#xff0c;虚拟机安装教程和镜像添加可参考该博主 按照教程安装成功 安装tools&#xff0c;但是我的弹不出来那个压缩包&…

ssm126基于HTML5的出租车管理系统+jsp(论文+源码)_kaic

设计题目&#xff1a;出租车管理系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以…

游戏引擎学习第14天

视频参考:https://www.bilibili.com/video/BV1iNUeYEEj4/ 1. 为什么关注内存管理&#xff1f; 内存分配是潜在的失败点&#xff1a; 每次进行内存分配&#xff08;malloc、new等&#xff09;时&#xff0c;都可能失败&#xff08;例如内存不足&#xff09;。这种失败会引入不稳…

阿里云引领智算集群网络架构的新一轮变革

阿里云引领智算集群网络架构的新一轮变革 云布道师 11 月 8 日~ 10 日在江苏张家港召开的 CCF ChinaNet&#xff08;即中国网络大会&#xff09;上&#xff0c;众多院士、教授和业界技术领袖齐聚一堂&#xff0c;畅谈网络未来的发展方向&#xff0c;聚焦智算集群网络的创新变…

【更新至2023】A股上市公司企业突破性创新、渐进性创新数据(2000-2023年)

测算方式&#xff1a;参考C刊《财经问题研究》胡山&#xff08;2022&#xff09;老师的研究&#xff0c;用当年获得授权的发明专利数量加 1 后取自然对数来衡量企业突破性创新 ( Invention) ; 用非发明专利 ( 包括实用新型专利和外观设计专利) 授权量加 1 后取自然对数来衡量企…

【Android、IOS、Flutter、鸿蒙、ReactNative 】启动页

Android 设置启动页 自定义 splash.xml 通过themes.xml配置启动页背景图 IOS 设置启动页 LaunchScreen.storyboard 设置为启动页 storyboard页面绘制 Assets.xcassets 目录下导入图片 AppLogo Flutter 设置启动页 Flutter Android 设置启动页 自定义 launch_background.xm…

Elasticsearch:管理和排除 Elasticsearch 内存故障

作者&#xff1a;来自 Elastic Stef Nestor 随着 Elastic Cloud 提供可观察性、安全性和搜索等解决方案&#xff0c;我们将使用 Elastic Cloud 的用户范围从完整的运营团队扩大到包括数据工程师、安全团队和顾问。作为 Elastic 支持代表&#xff0c;我很乐意与各种各样的用户和…

Jmeter基础篇(24)Jmeter目录下有哪些文件夹是可以删除,且不影响使用的呢?

一、前言 Jmeter使我们日常做性能测试最常用的工具之一啦&#xff01;但是我们在和其他同学协同工作的时候&#xff0c;偶尔也会遇到一些问题&#xff0c;例如我想要给别人发送一个Jmeter工具包&#xff0c;但这个文件包往往会很大&#xff0c;比较浪费流量和空间&#xff0c;…

排序算法(基础)大全

一、排序算法的作用&#xff1a; 排序算法的主要作用是将一组数据按照特定的顺序进行排列&#xff0c;使得数据更加有序和有组织。 1. 查找效率&#xff1a;通过将数据进行排序&#xff0c;可以提高查找算法的效率。在有序的数据中&#xff0c;可以使用更加高效的查找算法&…

如何在 WordPress 中轻松强制所有用户退出登录

作为一名长期管理 WordPress 网站的站长&#xff0c;我深知维护网站安全性的重要性。尤其是在面对会员网站或付费内容平台时&#xff0c;确保所有用户的登录状态是最新的&#xff0c;是维持网站正常运营的关键之一。今天&#xff0c;我就分享一下如何通过简单的步骤&#xff0c…

速通前端篇 —— HTML

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;速通前端 目录 HTML的介绍 如何创建HTML文件 HTML 文件基本结构 HTML常用标签 title标签 标题标签 h1-h6 段落标签 p 换行标签 b…

当微软windows的记事本被AI加持

1985年&#xff0c;微软发布了Windows 1.0&#xff0c;推出了一款革命性的产品&#xff1a;记事本&#xff08;Notepad&#xff09;。这款软件旨在鼓励使用一种未来主义的新设备——鼠标&#xff0c;并让人们可以不依赖VI等键盘工具就能书写文本和编写代码。记事本因其简洁和高…

LSTM(长短期记忆网络)详解

1️⃣ LSTM介绍 标准的RNN存在梯度消失和梯度爆炸问题&#xff0c;无法捕捉长期依赖关系。那么如何理解这个长期依赖关系呢&#xff1f; 例如&#xff0c;有一个语言模型基于先前的词来预测下一个词&#xff0c;我们有一句话 “the clouds are in the sky”&#xff0c;基于&…

Vulnhub靶场 Billu_b0x 练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 文件包含2. SQL注入3. 文件上传4. 反弹shell5. 提权&#xff08;思路1&#xff1a;ssh&#xff09;6. 提权&#xff08;思路2&#xff1a;内核&#xff09;7. 补充 0x04 总结 0x00 准备 下载链接&#…

重拾CSS,前端样式精读-媒体查询

前言 本文收录于CSS系列文章中&#xff0c;欢迎阅读指正 说到媒体查询&#xff0c;大家首先想到的可能是有关响应式的知识点&#xff0c;除此之外&#xff0c;它还可以用于条件加载资源&#xff0c;字体大小&#xff0c;图像和视频的优化&#xff0c;用户界面调整等等方面&am…

普通用户切换到 root 用户不需要输入密码配置(Ubuntu20)

在 Ubuntu 系统中&#xff0c;允许一个普通用户切换到 root 用户而不需要输入密码&#xff0c;可以通过以下步骤配置 sudo 设置来实现。 步骤&#xff1a; 打开 sudoers 文件进行编辑&#xff1a; 在终端中&#xff0c;输入以下命令来编辑 sudoers 文件&#xff1a; sudo visu…

MySQL系统优化

文章目录 MySQL系统优化第一章&#xff1a;引言第二章&#xff1a;MySQL服务架构优化1. 读写分离2. 水平分区与垂直分区3. 缓存策略 第三章&#xff1a;MySQL配置优化1. 内存分配优化Buffer Pool 的优化查询缓存与表缓存Key Buffer 2. 连接优化最大连接数会话超时连接池 3. 日志…

菲涅耳全息图

菲涅耳全息图&#xff1a;记录介质在物光波场的菲涅耳衍射区(物体到记录介质表面的距离在菲涅耳衍射区内)。 一、点源全息图的记录和再现 1.1 记录 设物光波和参考光波是从点源O(xo, yo, zo)和点源 R(xr, yr, zr)发出的球面波, 波长为λ1, 全息底片位于z0 的平面上, 与两个点源…