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

目录

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Aria2-CVE-2023-39141漏洞分析

前言&#xff1a; 在偶然一次的渗透靶机的时候&#xff0c;上网查询Aria2的历史漏洞&#xff0c;发现了这个漏洞&#xff0c;但是网上并没有对应的漏洞解释&#xff0c;于是我就就源代码进行分析&#xff0c;发现这是一个非常简单的漏洞&#xff0c;于是发这篇文章跟大家分享一…

androidstudio入门到放弃配置

b站视频讲解传送门 android_studio安装包&#xff1a;https://developer.android.google.cn/studio?hlzh-cn 下载安装 开始创建hello-world 1.删除缓存 文件 下载gradle文件压缩&#xff1a;gradle-8.9用自己创建项目时自动生成的版本即可&#xff0c;不用和我一样 https://…

河道无人机雷达测流监测系统由哪几部分组成?

在现代水利管理中&#xff0c;河道无人机雷达监测系统正逐渐成为一种重要的工具&#xff0c;为河道的安全和管理提供了强大的技术支持。那么&#xff0c;这个先进的监测系统究竟由哪几部分组成呢&#xff1f; 河道无人机雷达监测系统工作原理 雷达传感器通过发射电磁波或激光束…

Mac上详细配置java开发环境和软件(更新中)

文章目录 概要JDK的配置JDK下载安装配置JDK环境变量文件 Idea的安装Mysql安装和配置Navicat Premium16.1安装安装Vscode安装和配置Maven配置本地仓库配置阿里云私服Idea集成Maven 概要 这里使用的是M3型片 14.6版本的Mac 用到的资源放在网盘 链接: https://pan.baidu.com/s/17…

CKA认证 | Day3 K8s管理应用生命周期(上)

第四章 应用程序生命周期管理&#xff08;上&#xff09; 1、在Kubernetes中部署应用流程 1.1 使用Deployment部署Java应用 在 Kubernetes 中&#xff0c;Deployment 是一种控制器&#xff0c;用于管理 Pod 的部署和更新。以下是使用 Deployment 部署 Java 应用的步骤&#x…

ffmpeg编程入门

文章目录 ffmpeg流程常用的音视频术语常用概念复用器编解码器ffmpeg的整体结构注册组件相关封装格式相关函数的调用流程 相关的ffpmeg数据结构简介数据结构之间的关系 ffmpeg流程 图中的函数 以及结构体都是ffmpeg自带提供的 ffmpeg打开的时候 和其他io操作差不多 有一个类似句…

函数指针示例

目录&#xff1a; 代码&#xff1a; main.c #include <stdio.h> #include <stdlib.h>int Max(int x, int y); int Min(int x, int y);int main(int argc, char**argv) {int x,y;scanf("%d",&x);scanf("%d",&y);int select;printf(&q…

间接采购管理:主要挑战与实战策略

间接采购支出会悄然消耗掉企业的现金流&#xff0c;即使是管理完善的公司也难以避免。这是因为间接支出不直接关联特定客户、产品或项目&#xff0c;使采购人员难以跟踪。但正确管理间接支出能为企业带来显著收益——前提是要有合适的工具。本文将分享管理间接支出的关键信息与…

TCP(下):三次握手四次挥手 动态控制

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! TCP(上)&#xff1a;成熟可靠的传输层协议-CSDN博客 &#x1f95d;在上篇博客中&#xff0c;我们针对TCP的特性,报文结构,连接过程以及相对于其他协议的区别进行了探讨&#xff0c;提供了初步的理解和概览。本…

ASP.NET 部署到IIS,访问其它服务器的共享文件 密码设定

asp.net 修改上面的 IIS需要在 配置文件 添加如下内容 》》》web.config <system.web><!--<identity impersonate"true"/>--><identity impersonate"true" userName"您的账号" password"您的密码" /><co…

python实现十进制转换二进制,tkinter界面

目录 需求 效果 代码实现 代码解释 需求 python实现十进制转换二进制 效果 代码实现 import tkinter as tk from tkinter import messageboxdef convert_to_binary():try:# 获取输入框中的十进制数decimal_number int(entry.get())# 转换为二进制binary_number bin(de…

现代密码学|古典密码学例题讲解|AES数学基础(GF(2^8)有限域上的运算问题)| AES加密算法

文章目录 古典密码凯撒密码和移位变换仿射变换例题多表代换例题 AES数学基础&#xff08;GF&#xff08;2^8&#xff09;有限域上的运算问题&#xff09;多项式表示法 | 加法 | 乘法X乘法模x的四次方1的乘法 AES加密算法初始变换字节代换行移位列混合轮密钥加子密钥&#xff08…

ubuntu使用DeepSpeech进行语音识别(包含交叉编译)

文章目录 前言一、DeepSpeech编译二、DeepSpeech使用示例三、核心代码分析1.创建模型核心代码2.识别过程核心代码 四、交叉编译1.交叉编译2.使用 总结 前言 由于工作需要语音识别的功能&#xff0c;环境是在linux arm版上&#xff0c;所以想先在ubuntu上跑起来看一看&#xff…

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

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

PyQt5 加载UI界面与资源文件

步骤一: 使用 Qt Designer 创建 XXX.ui文件 步骤二: 使用 Qt Designer 创建 资源文件 步骤三: Python文件中创建相关类, 使用 uic.loadUi(mainwidget.ui, self ) 加载UI文件 import sys from PyQt5 import QtCore, QtWidgets, uic from PyQt5.QtCore import Qt f…

7.高可用集群架构Keepalived双主热备原理

一. 高可用集群架构Keepalived双主热备原理 (1)主机+备机keepalived配置(192.168.1.171) ! Configuration File for keepalivedglobal_defs {# 路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_101 } #计算机节点(主机配置) vrrp_instance VI_1 {</

RHCE的学习(19)

对于RHCE的学习&#xff08;15-18&#xff09;重点总结 详细的操作还是要看之前的笔记&#xff08;甚至是RHCSA的笔记&#xff09; 1.什么是shell 一种命令解释器&#xff0c;既是用户交互的界面&#xff0c;也是控制系统的脚本语言 2.shell解释器的类型 &#xff08;bash--sh&…

微服务即时通讯系统的实现(客户端)----(2)

目录 1. 将protobuf引入项目当中2. 前后端交互接口定义2.1 核心PB类2.2 HTTP接口定义2.3 websocket接口定义 3. 核心数据结构和PB之间的转换4. 设计数据中心DataCenter类5. 网络通信5.1 定义NetClient类5.2 引入HTTP5.3 引入websocket 6. 小结7. 搭建测试服务器7.1 创建项目7.2…

【功耗现象】com.gorgeous.lite后台Camera 使用2小时平均电流200mA耗电量400mAh现象

现象 轻颜相机(com.gorgeous.lite)后台Camera 使用2小时平均电流200mA(BugReport提供的电流参考数据),耗电量400mAh 即耗电占比(200mA*2h)/(12.83h*52.68mA )400mAh/623mAh62% CameraOct 10 202321:03:08 - 23:03:372h16m15s859ms to 4h16m44s984msactive duration: 2h 0m 29…

蓝桥杯每日真题 - 第15天

题目&#xff1a;&#xff08;钟表&#xff09; 题目描述&#xff08;13届 C&C B组B题&#xff09; 解题思路&#xff1a; 理解钟表指针的运动&#xff1a; 秒针每分钟转一圈&#xff0c;即每秒转6度。 分针每小时转一圈&#xff0c;即每分钟转6度。 时针每12小时转一圈…