Java-自动拆箱/装箱/缓存/效率

为什么基本类型需要包装类?

  • 泛型与集合支持问题:基本数据类型在使用上虽然方便、简单且高效,但像泛型以及集合元素的存储等场景并不支持基本数据类型,而包装类可以解决这个问题,使其能更好地融入到一些需要对象类型的机制中。
  • 面向对象思维:基本数据类型不符合面向对象编程的思维方式,包装类把基本数据类型 “包装” 成了对象形式,更契合面向对象的编程模式。
  • 提供实用方法:包装类提供了很多实用的方法,例如 Integer 类中的 toHexString (int i) 可以将整数转换为十六进制字符串,parseInt (String s) 方法能把字符串解析为整数,方便了开发过程中的各种操作。

Long 或 Integer 如何比较大小?

  • 错误方法

        使用 == 。因为 Long 与 Integer 都是包装类型,是对象。“==” 比较的是对象的引用地址,而不是对象所包装的基本类型的值。

        使用 equals() 方法。因为 equals() 方法只能比较同类型的类,例如两个都是 Integer 类型。

  • 正确方法

        先使用 LongValue() 或 intValue() 方法来得到它们的基本类型的值然后再使用 == 比较。

拆箱与装箱原理

装箱就是将基本数据类型转化为包装类型,那么拆箱就是将包装类型转化为基本数据类型。

示例:

package org.example.a;
public class Demo{
    public static void main(String[] args) {

        //自动装箱,底层其实执行了Integer a=Integer.valueOf(10);
        Integer a = 10;

        //自动拆箱,底层其实执行了int b=a.intValue();
        int b = a;
    }
}

实例:自动拆装箱

实例1:基本类型与其包装类

package org.example.a;
public class Demo {
    public static void main(String[] args) {
        int int1 = 12;
        int int2 = 12;
        Integer integer1 = new Integer(12);
        Integer integer2 = new Integer(12);
        System.out.println("int1 == int2         : " + (int1 == int2));
        System.out.println("int1 == integer1     : " + (int1 == integer1));
        System.out.println("integer1 == integer2 : " + (integer1 == integer2));
    }
}

运行结果:

int1 == int2         : true
int1 == integer1     : true
integer1 == integer2 : false

解释:

当进行“int1 == int2” 比较时,就是普通的基本类型值的比较,结果为 true。

对于“int1 == integer1” 比较,由于 Integer 与 int 进行 “==” 比较时,Integer 会自动拆箱成 int 类型,相当于两个 int 类型比较,所以结果也是 true。

而 “integer1 == integer2” 比较,因为它们是不同的对象实例(通过 new 创建的两个独立对象,即使包装的值相同,对象引用地址不同),所以结果为 false。

实例2:自动拆箱引起的异常

package com.example.a;
public class Demo {
    public static void main(String[] args) {
        Integer a = null;
        System.out.println(2 == a);
    }
}

运行结果:

Exception in thread "main" java.lang.NullPointerException
    at com.example.a.Demo.main(Demo.java:6)

解释:

因为基本类型与包装类型进行比较时会自动拆箱,也就是会调用 a.intValue () 方法来获取基本类型的值,但此时 a 为 null,调用 null 的方法就会报空指针异常(NullPointerException)。

实例3:基本类型与Object

package org.example.a;
public class Demo {
    public static void main(String[] args) {
        Object object = true;
        System.out.println(object);
        boolean b = (boolean)object;
        System.out.println(b);
        System.out.println(b == true);
    }
}

运行结果:

true
true
true

解释:

在代码 Object object = true; 这一行中,发生了自动装箱(autoboxing)操作。对于boolean基本类型,其对应的包装类型是Boolean。当把true(基本类型boolean的值)赋给Object类型的变量object时,Java 会自动将true这个基本类型值包装成Boolean类型的对象,然后再赋值给object变量。从本质上来说,这一行代码等同于 Object object = new Boolean(true);,只不过编译器帮我们自动完成了从基本类型到包装类型的转换这一过程,这个机制使得代码编写更加简洁和方便,符合 Java 中面向对象操作的风格,因为在很多面向对象的场景里(比如将值存储在集合中,集合元素要求是对象类型),基本类型需要先转换为包装类型才能参与操作。

代码 boolean b = (boolean)object; 进行了强制类型转换操作。虽然object的实际类型是Boolean(前面经过自动装箱转换而来),但它声明的类型是Object,在 Java 中如果要获取其包装的基本类型的值,需要进行显式的类型转换。这里通过 (boolean) 这种强制类型转换的语法,告诉编译器要把object所代表的对象转换回基本类型boolean。编译器会检查object实际指向的对象是否能转换为boolean类型(在这里因为它本身就是由boolean值自动装箱而来的Boolean对象,所以是可以转换的),然后提取出其包装的true这个基本类型值,并赋值给boolean类型的变量b

执行 System.out.println(b == true);,这里就是简单的基本类型boolean值之间的比较,因为b的值就是true,所以比较结果为true,控制台输出 true

实例:缓存问题

package org.example.a;
public class Demo{
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        Integer c = 128;
        Integer d = 128;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}

执行结果:

true
false

解释:

valueOf() 源码:

//private static class IntegerCache {
    //    static final int low = -128;
    //    static final int high = 127;
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

Integer 有一个缓存机制,在其 valueOf 方法的实现中,会判断传入的 int 值是否在缓存范围([-128, 127])内,如果在这个范围内,就会直接返回 Integer 缓存数组中相应对象的引用,如果超出这个范围(大于 127 或小于 -128),则会重新创建一个 Integer 实例并返回。

实例代码中,定义了 Integer 类型变量 a、b 赋值为 127,c、d 赋值为 128,“a == b” 比较结果为 true,是因为 127 在缓存范围内,a 和 b 指向的是缓存中同一个 Integer 对象;而 “c == d” 比较结果为 false,因为 128 超出了缓存范围,c 和 d 是通过 new 创建出来的不同对象。

其他包装类的缓存:

Byte、Short、Integer、Long、Character的valueOf()实现机制类似。

包装类说明
Byte相同值的Byte比较永远返回true。因为byte取值范围就是[-128,127]。
Short、Integer、Long相同值在[-128,127]则返回true,不在则返回false
Character要返回true,只需保证i <= 127。因为char最小值为0,本来就大于等于-128。
Float、Double永远返回false。因为其永远返回新创建的对象,因为一个范围内的整数是有限的,但是小数却是无限的,无法保存在缓存中。
Boolean只有两个对象,要么是true的Boolean,要么是false的Boolean,只要boolean的值相同,Boolean就相等。

实例:效率问题

package org.example.a;
public class Demo {
    public static void main(String[] args) {
        long t1 = System.currentTimeMillis();
        Long sum = 0L;
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            sum += i;
        }
        long t2 = System.currentTimeMillis();
        System.out.println(t2 - t1);
    }
}

运行结果:

6218

如果将 sum 改为 long (基本类型),运行结果:

624

解释:

在涉及大量数值运算的场景中,使用基本类型通常比使用对应的包装类型效率更高,就是因为包装类型存在自动拆箱、装箱以及复杂的对象内存管理等额外开销,而基本类型能更直接快速地进行数值处理。

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

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

相关文章

计算机毕业设计Python中华古诗词知识图谱可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析模型 自然语言处理NLP 机器学习 深度学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

微服务网关SpringCloudGateway、Kong比较

网关产品 1. Spring Cloud Gateway 基本信息 Spring Cloud Gateway是Spring Cloud生态系统中的一个组件&#xff0c;基于Spring 5、Project Reactor和Spring Boot 2构建。它旨在为微服务架构提供一种简单而有效的API网关解决方案。 功能特点 路由功能强大&#xff1a;使用Rou…

实现基于分布式的LAMP架构+NFS实时同步到备份服务器

概述 项目计划用WordPress搭建一个博客系统, 为了性能更好,两个服务器都对外提供WordPress博客系统服务, 数据放在MySQL服务器, 有些上传的图片发送到NFS服务器上&#xff0c;并且把NFS数据实时同步到一个备份服务器上。 服务名称IP地址DNS10.0.0.200WEB110.0.0.201W…

【NVIDIA orin nx 安装ultralytics yolov11】

注意:不同用户安装的python可能会在不同的路径,因此不同的pip管理会导致安装的 torch和torchvision会在不同的路径下 记得区分用户来运行yolo 一、确认系统 JetPack 版本 此处使用5.1.1 1、查看JetPack 版本 jtop二、安装 ultralytics、pytorch、torchvision、onnxruntime…

Linux系统挂载exfat格式U盘教程,触觉智能RK3562开发板演示

本文介绍Linux系统&#xff08;Ubuntu/Debian通用&#xff09;挂载exfat格式U盘的方法&#xff0c;触觉智能RK3562开发板演示&#xff0c;搭载4核A53处理器&#xff0c;主频高达2.0GHz&#xff1b;内置独立1Tops算力NPU&#xff0c;可应用于物联网网关、平板电脑、智能家居、教…

【Vulkan入门】08-CreateRenderPass

目录 先叨叨git信息关键代码TestPipeLine::CreateRenderPass() 先叨叨 上篇已经为Pipeline编写好了程序&#xff08;Shader&#xff09;。接下来要为Pipeline创建RenderPass。 关于RenderPass&#xff0c;在【Vulkan入门】06-Pipeline介绍中已经作了简单的介绍。这里再详细说一…

从 HTTP 到 HTTPS 再到 HSTS

近些年&#xff0c;随着域名劫持、信息泄漏等网络安全事件的频繁发生&#xff0c;网站安全也变得越来越重要&#xff0c;也促成了网络传输协议从 HTTP 到 HTTPS 再到 HSTS 的转变。 HTTP HTTP&#xff08;超文本传输协议&#xff09; 是一种用于分布式、协作式和超媒体信息系…

01-Chromedriver下载与配置(mac)

下载地址&#xff1a; 这里我用的最后一个&#xff0c;根据自己chrome浏览器选择相应的版本号即可 ChromeDriver官网下载地址&#xff1a;https://sites.google.com/chromium.org/driver/downloads ChromeDriver官网最新版下载地址&#xff1a;https://googlechromelabs.git…

面试技术点之安卓篇

一、基础 二、高级 三、组件 Android中SurfaceView和TextureView有什么区别&#xff1f; 参考 Android中SurfaceView和TextureView有什么区别&#xff1f; 四、三方框架 五、系统源码 六、性能优化

架构13-持久化存储

零、文章目录 架构13-持久化存储 1、Kubernetes 存储设计 &#xff08;1&#xff09;存储设计考量 **设计哲学&#xff1a;**Kubernetes 遵循用户通过资源和声明式 API 描述意图&#xff0c;Kubernetes 根据意图完成具体操作。**复杂性&#xff1a;**描述用户的存储意图本身…

可视化建模以及UML期末复习----做题篇

一、单项选择题。&#xff08;20小题&#xff0c;每小题2分,共40分&#xff09; 1、UML图不包括&#xff08; &#xff09; A、用例图 B、状态机图 C、流程图 D、类图 E、通信图 答案&#xff1a;C、流程图 UML中不包括传统意义上的流程图&#xff0c;流程图通常是指B…

idea_maven详解

秒懂Maven maven简介maven安装和配置maven本地配置maven工程的GAVP创建maven工程项目结构说明项目构建说明 Maven依赖管理核心信息配置依赖管理配置依赖信息查询依赖范围设置依赖属性配置依赖下载失败错误解决Build构建配置依赖传递依赖冲突 maven工程继承继承作用应用场景继承…

vue3+vite纯前端实现自动触发浏览器刷新更新版本内容,并在打包时生成版本号文件

前言 在前端项目中&#xff0c;有时候为了实现自动触发浏览器刷新并更新版本内容&#xff0c;可以采取一系列巧妙的措施。我的项目中是需要在打包时候生成一个version.js文件&#xff0c;用当前打包时间作为版本的唯一标识&#xff0c;然后打包发版 &#xff0c;从实现对版本更…

鸿蒙实现应用通知

目录&#xff1a; 1、应用通知的表现形式2、应用通知消息的实现1、发布普通文本类型通知2、发布进度类型通知3、更新通知4、移除通知 3、设置通知道通展示不同形式通知4、设置通知组5、为通知添加行为意图1、导入模块2、创建WantAgentInfo信息3、创建WantAgent对象4、构造Notif…

2024 年 MySQL 8.0.40 安装配置、Workbench汉化教程最简易(保姆级)

首先到官网上下载安装包&#xff1a;http://www.mysql.com 点击下载&#xff0c;拉到最下面&#xff0c;点击社区版下载 windows用户点击下面适用于windows的安装程序 点击下载&#xff0c;网络条件好可以点第一个&#xff0c;怕下着下着断了点第二个离线下载 双击下载好的安装…

【RabbitMQ】RabbitMQ中核心概念交换机(Exchange)、队列(Queue)和路由键(Routing Key)等详细介绍

博主介绍&#xff1a;✌全网粉丝21W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

【C++笔记】AVL树的深度剖析

【C笔记】AVL树的深度剖析 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】AVL树的深度剖析前言一. AVL树的概念二.AVL树的实现2.1 AVL树的结构2.2 AVL树的插入2.3 平衡因子更新 三.旋转3.1旋转的原则3.2右单旋3.3左…

Ubuntu 环境安装 之 RabbitMQ 快速入手

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;RabbitMQ &#x1f4da;本系列文章为个人学…

贪心算法专题(四)

目录 1. 单调递增的数字 1.1 算法原理 1.2 算法代码 2. 坏了的计算器 2.1 算法原理 2.2 算法代码 3. 合并区间 3.1 算法原理 3.2 算法代码 4. 无重叠区间 4.1 算法原理 4.2 算法代码 5. 用最少数量的箭引爆气球 5.1 算法原理 ​5.2 算法代码 1. 单调递增的数字…

IAR环境下的FlashLoader设计

目录 1.为什么要Flash Loader 2.Flash Loader设计细节 2.1 简单的代码框架 2.2 迷人的宏使用 2.3 关键的配置文件 3.dmac和mac文件 4.小结 搞国产车规芯片&#xff0c;IAR是必不可少的编译调试集成工具&#xff0c;历史背景不赘述&#xff0c;今天主要聊聊基于IAR的Fla…