Java基础——自动装箱与拆箱

自动装箱与拆箱

  • 装箱:将基本类型用包装器类型包装起来
  • 拆箱:将包装器类型转换为基本类型

请看示例:

public class Main {public static void main(String[] args) {Integer a = 100;Integer b = 100;Integer c = 128;Integer d = 128;System.out.println(a==b);System.out.println(c==d);}
}

上面这段代码的输出结果:true false
很多人看到这个结果会很疑惑,为什么会是一个 true 一个 flase

其实从源码中可以很容易找到原因.
首先找到 Integer 方法中的 valueOf 方法

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

当不满足 if 语句中的条件,就会重新创建一个对象返回,那结果必然不相等。继续打开IntegerCache 可以看到

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

代码挺长,大概说的就是在通过 valueOf 方法创建 Integer 对象的时候,如果数值在[-128,127]
之间,便返回指向 IntegerCache.cache 中已经存在的对象的引用;否则创建一个新的 Integer
对象。所以上面代码中 a 与 b 相等, c 与 d 不相等。

在看下面的代码会输出什么

public class Main {public static void main(String[] args) {Double a = 1.0;Double b = 1.0;Double c = 2.0;Double d = 2.0;System.out.println(a==b);System.out.println(c==d);}
}

flase
flase
采用同样的方法,可以看到 Double 的 valueOf 方法,每次返回都是重新 new 一个新的对象,所以上面代码中的结果都不想等。

public static Double valueOf(double d) {return new Double(d);
}

最后再看这段代码的输出结果

public class Main {public static void main(String[] args) {Boolean a = false;Boolean b = false;Boolean c = true;Boolean d = true;System.out.println(a==b);System.out.println(c==d);}
}

true
true

继续看 valueOf 方法

public static Boolean valueOf(boolean b) {return (b ? TRUE : FALSE);}

再看看 TRUE 和 FALSE 是个什么东西,是两个静态成员属性。

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

结论 : Integer 、 Short 、 Byte 、 Character 、 Long 这几个类的 valueOf 方法的实现是类似
的。 Double 、 Float 的 valueOf 方法的实现是类似的。然后是 Boolean 的 valueOf 方法是单独一组的。
Integer i = new Integer(xxx) 和 Integer i =xxx 的区别
这两者的区别主要是第一种会触发自动装箱,第二者不会
最后看看下面这段程序的输出结果

public class Main {public static void main(String[] args) {Integer a = 1;Integer b = 2;Integer c = 3;Long g = 3L;int int1 = 12;int int2 = 12;Integer integer1 = new Integer(12);Integer integer2 = new Integer(12);Integer integer3 = new Integer(1);System.out.println("c==(a+b) ->"+ (c==(a+b)));System.out.println("g==(a+b) ->" + (g==(a+b)));System.out.println( "c.equals(a+b) ->" + (c.equals(a+b)));System.out.println( "g.equals(a+b) ->" + (g.equals(a+b)));System.out.println("int1 == int2 -> " + (int1 == int2));System.out.println("int1 == integer1 -> " + (int1 == integer1));System.out.println("integer1 == integer2 -> " + (integer1 == integer2));System.out.println("integer3 == a1 -> " + (integer3 == a));}
}

c==(a+b) ->true
g==(a+b) ->true
c.equals(a+b) ->true
g.equals(a+b) ->false
int1 == int2 -> true
int1 == integer1 -> true
integer1 == integer2 -> false
integer3 == a1 -> false

下面简单解释这些结果。
1.当== 运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果 其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。所 以 c==a+b , g==a+b 为 true 。

2.而对于 equals 方法会先触发自动拆箱过程,再触发自动装箱过程。也就是说a+b,会先各调 用 intValue 方法,得到了加法运算后的数值之后,便调用 Integer.valueOf 方法,再进行 equals 比较。所以 c.equals(a+b)为 true 。而对于 g.equals(a+b) , a+b 会先拆箱进行相加 运算,在装箱进行 equals 比较,但是装箱后为Integer , g 为 Long ,所以 g.equals(a+b) 为 false 。

  1. int1 == int2 为 true 无需解释, int1 == integer1 ,在进行比较时, integer1 会先进行 一个拆箱操作变成 int 型在进行比较,所以 int1 == integer1 为 true 。
  1. integer1 == integer2 -> false 。 integer1 和 integer2 都是通过 new 关键字创建的,可以 看成两个对象,所以 integer1 == integer2 为 false 。 integer3 == a1 ->false , integer3 是一个对象类型,而 a1 是一个常量它们存放内存的位置不一样,所以 integer3 == a1 为false ,具体原因可学习下java的内存模型。

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

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

相关文章

智慧物流:实现供应链的技术升级

智慧物流不仅是物流管理系统的智能化升级&#xff0c;更是以物联网、大数据分析等技术手段为基础的一种高效、智能的供应链解决方案。通过实时监控、数据分析和智能优化&#xff0c;智慧物流将传统物流的各个环节有效连接起来&#xff0c;实现信息流、资金流和物流的无缝对接。…

AMD模块的使用案例-基于普通htm

AMD模块的使用案例-基于普通html 实现过程结果 实现过程 AMD 是一种适用于浏览器环境的模块化规范&#xff0c;主要用于异步加载模块。RequireJS 是实现 AMD 的一个流行库。 ​ 使用案例&#xff1a; 文件目录&#xff1a; index.html&#xff0c;使用<script data-main&…

【每天学会一个渗透测试工具】AppScan安装及使用指南

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 https://www.hcl-software.com/appscan AppScan是一种综合型漏洞扫描工具&#xff0c;采用SaaS解决方案&#xff0c;它将所以…

打造完美启动页:关键策略与设计技巧

启动页&#xff08;Splash Screen&#xff09;设计是指在应用程序启动时&#xff0c;首先展示给用户的界面设计。这个界面通常在应用加载或初始化期间显示&#xff0c;其主要目的是为用户提供一个视觉缓冲&#xff0c;展示品牌标识&#xff0c;并减少用户在等待过程中的焦虑感。…

【锐捷】VSU环境下部署VAC

配置要求 1.两台核心交换机部署VSU&#xff0c;Domain ID为1&#xff0c;S1的Switch ID为1&#xff0c;优先级为150&#xff0c;设备描述为VSU-S1&#xff1b;S2的Switch ID为2&#xff0c;优先级为120&#xff0c;设备描述为VSU-S2&#xff1b;两台设备的G0/48口用于BFD双机检…

python从入门到精通4:变量赋值

在Python编程中&#xff0c;变量赋值是编程基础中的基础&#xff0c;但其中也包含了许多深入的概念和技巧。本教程将深入探讨Python变量赋值的各个方面&#xff0c;包括基本赋值、多重赋值、链式赋值、增量赋值。 一、基本赋值 Python中的变量赋值非常简单直观&#xff0c;你…

【Golang - 90天从新手到大师】Day06 - 数组

系列文章合集 Golang - 90天从新手到大师 数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合 定义一个数组 格式: var name [n]type n为数组长度,n>0 且无法修改,type为数组的元素类型如: var a [2]int上面的例子定义了一个长度为2,元素类型为int的数组…

PostgreSQL源码分析——缓冲区管理器

这里我们分析一下PG数据库缓冲区的代码。缓冲区是十分重要的&#xff0c;对数据库的性能和稳定性有着直接的影响。缓冲区是数据库SQL计算层与外部存储&#xff08;磁盘&#xff09;交互的关键。数据页的落盘与读取&#xff0c;都要经过缓冲区。 README src/backend/storage/…

解决企业微信内嵌H5页面导航栏返回上一级是空白页面问题

在项目中,产品要求返回上一级不能空白页,可以是工作台,所以要引入企业微信的返回按钮的用法,以下是详细步骤: 1.引入企业微信的版本内容 <script src"https://res.wx.qq.com/wwopen/js/jsapi/jweixin-1.0.0.js"></script> 在public底下的index.html底…

pdf只要前几页,pdf怎么只要前几页

在现代办公和学习环境中&#xff0c;PDF文件已成为我们日常处理信息的重要工具。然而&#xff0c;有时我们并不需要整个PDF文件的内容&#xff0c;而只是其中的几页。那么&#xff0c;如何高效地提取PDF文件中的特定页面呢&#xff1f;本文将为您介绍几种实用的方法。 打开 “ …

法大大亮相国家级期刊,助力数字政务有实“例”!

近日&#xff0c;在最新发布的国家级学术期刊《市场监督管理》中&#xff0c;法大大作为国内领先的电子签厂商亮相&#xff0c;这也是电子签行业的“第一次”。 截自《市场监督管理》2024年第12期 《市场监督管理》杂志于1953年创刊&#xff0c;是中国工商出版社主办的一本学术…

Uniapp导航栏右侧自定义图标文字按钮

1.再pages.js中找到该页面内容&#xff1a; 进行如下设置&#xff1a; {"path" : "pages/finishPfpOrder/finishPfpOrder","style" : {"navigationBarTitleText": "首件列表","navigationBarBackgroundColor": &…

【Vue-Vben-Admin】1、初次运行和介绍

【Vue-Vben-Admin】1、初次运行和介绍 Vben-Admin 初次运行和介绍 小小的介绍规定版本文件树安装依赖运行项目 小小的介绍 一款 Vue3 Typescript4 Vite2 后台管理项目&#xff0c;功能挺多的&#xff0c;还有组件库 规定版本 此个人文档规定版本为 2.8.0&#xff0c;可能版本…

复习笔记二(动态规划法)

工作指派问题&#xff08;20 分&#xff09; 设有 n 件工作&#xff0c; n 个人&#xff0c;每个人只能做一件工作&#xff0c;每件工作只能安排给一个 人&#xff0c;已知每个人做每件工作的耗费&#xff0c;请设计分支限界算法求解最少耗费的工作指 派。 要求&#xf…

android 获取java c++线程id

android.os.Process.myTid()#include <unistd.h> gettid()

如何查看公网IP?

什么是公网IP&#xff1f; 公网IP&#xff08;Internet Protocol&#xff09;是指分配给互联网上的计算机设备的唯一标识符。公网IP地址是由互联网服务提供商&#xff08;ISP&#xff09;分配给用户设备&#xff0c;使其可以与全球范围内的其他设备进行通信。公网IP地址通常采…

【OpenVINO™】使用 OpenVINO™ C# 异步推理接口部署YOLOv8 ——在Intel IGPU 上速度依旧飞起!!

OpenVINO Runtime支持同步或异步模式下的推理。Async API的主要优点是&#xff0c;当设备忙于推理时&#xff0c;应用程序可以并行执行其他任务&#xff08;例如&#xff0c;填充输入或调度其他请求&#xff09;&#xff0c;而不是等待当前推理首先完成。 当我们使用异步API时&…

Type-C诱骗芯片LDR6500

随着科技的飞速发展&#xff0c;电子设备的智能化和便携化已成为趋势。在这个过程中&#xff0c;Type-C接口因其高速传输、正反可插以及强大的扩展能力&#xff0c;逐渐成为主流接口标准。然而&#xff0c;Type-C接口的广泛应用也带来了一系列挑战&#xff0c;其中之一便是如何…

千呼新零售2.0【更新日志】持续更新ing

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货等连锁店使用。 详细介绍请查看下…

存u盘里的视频没删除找不到了怎么办?别急,这几招来帮您

在数字化时代&#xff0c;U盘已成为我们随身携带、存储和传输文件的重要设备。然而&#xff0c;有时我们会突然发现存放在U盘中的视频文件不翼而飞&#xff0c;这常常让我们感到困扰和焦虑。视频文件可能包含了重要的工作资料、珍贵的家庭记忆或是无法再找回的独特素材。面对这…