百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

灵魂拷问:为什么short、byte会被提升为int?boolean到底多大?

ccwgpt 2024-12-02 15:58 44 浏览 0 评论

为什么short、byte会被提升为 int ?

在学习Java语法的时候,知道short 、byte、byte 类型在做运算符号的时候,都会默认提升为 int,例如下面的代码就是无法通过编译的,需要将等于号右边的强制转为 short 才可以。

public static void main(String[] args) {    short a = 1;    short b = 2;    a = a + b;           // 编译不过    short c = a + b;  // 编译不过}

为什么两个 short 相加会变成 int,有的人解释说,两个 short 相加可能溢出,所以用 int 来接就不会溢出,那这样的话,两个 int 相加岂不应该是 long 类型吗?其实本质的原因要从字节码开始讲起。

Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表次操作所需参数(称为操作数,Operands)而构成。

Java虚拟机的指令集中的大多数都对它们执行的操作的数据类型进行编码,例如 iload 指令,是将一个局部变量加载到操作栈,且这个局部变量必须是 int 类型。

由于操作码的长度为一个字节,这意味着指令集的操作码总数不可能超过256条,这也为设计包含数据类型的操作码带来了很大压力:如果每一种与数据类型相关的指令都支持Java虚拟机所有运行时数据类型的话,那指令的数量就会超出一个字节所能表示的数量范围了。

根据下表(出自 Table 2.11.1-A. Type support in the Java Virtual Machine instruction set),可以发现大部分指令都没有支持 byte、char 和 short 类型,甚至没有任何指令支持 boolean 类型。编译器会在编译器或运行期将 byte 和 short 类型带符号扩展为 int 类型, boolean 和 char 类型零位扩展为相应的 int 类型。与之类似,在处理 boolean、byte、char 和 short 类型的数组时,也会转为使用相应的 int 类型的字节码来处理指令。 因此,大多数对于 boolean、byte、char 和 short 类型数据的操作,实际都是使用 int 类型作为运算类型。另外还有第二点原因,在设计虚拟机时,主要考虑的是 32位体系,32位系统使用 4 字节是最节省,因为 CPU 只能 32位32位的寻址。

如果想详细查看各个指令,可以参考Java虚拟机规范


Java 中 boolean 到底多大?

我们继续深入思考, boolen 到底有多大? 在学 Java 的时候, 都说 byte、boolen 类型占 1字节,但上面又提到, byte 会被提升为 int 类型,那么就应该占了 4字节。没错,虚拟机规范只有 4字节 和 8字节类型(long、float), boolean、char、short 都是占了 4字节。

我们来看一例子。

public class Test {    byte aByte = 2;    short aShort = 3;        public void byteAdd() {        aByte = (byte) (aByte + 1);    }    public void shortAdd() {        aShort = (short) (aShort + 1);    }}

先编译此文件javac Test.java,查看 Class 内容,javap -verbose Test,摘取关键信息:

{  byte aByte;    descriptor: B    flags:  short aShort;    descriptor: S    flags:  public void byteAdd();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=3, locals=1, args_size=1         0: aload_0         1: aload_0         2: getfield      #2                  // Field aByte:B         5: iconst_1         6: iadd         7: i2b         8: putfield      #2                  // Field aByte:B        11: return  public void shortAdd();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=3, locals=1, args_size=1         0: aload_0         1: aload_0         2: getfield      #3                  // Field aShort:S         5: iconst_1         6: iadd         7: i2s         8: putfield      #3                  // Field aShort:S        11: return}

观察这两个方法,第一第二行目的是将对应的变量压入栈,第五行都是 iconst_1,将 int 类型的 1 压入栈中,然后使用 iadd 方法,将两个值相加,之后一个调用 i2b,一个调用 i2s 指令。我们随便查看一个i2s的命令介绍 jvms-6.5.i2s,它是这样描述的

The value on the top of the operand stack must be of type int. It is popped from the operand stack, truncated to a short, then sign-extended to an int result. That result is pushed onto the operand stack.

翻译过来大致是:

操作数堆栈顶部的值必须是int类型。它从操作数堆栈中弹出,截断为short,然后符号扩展为int结果。结果被推送到操作数堆栈上。

因此,可以看出 short、char 实际上也是占用了 和 int 一样大的字节的。那我们平时所说 short 是 2 字节的岂不是错误的?并不是,对于单个 byte、char、short 类型的数据,在内存中实际会占 4 字节,但这对于数组来说并不适用, byte 数组每个元素占 1 字节, char、short 数组都占 2 字节。

参考stackoverflow中的回答 Size of a byte in memory - Java,注意标注高亮的部分。

更多对基本类型的描述,可以查看Primitive Data Types

说完byte、char、short,我们再来看看对于 boolean 的描述,摘取部分信息 2.3.4. The boolean Type:

Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine int data type.


The Java Virtual Machine does directly support boolean arrays. Its newarray instruction (§newarray) enables creation of boolean arrays. Arrays of type boolean are accessed and modified using the byte array instructions baload and bastore (§baload, §bastore).


In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.

翻译大概如下:

尽管Java虚拟机定义了一种 boolean 类型,但对它的提供支持非常有限,没有专门的虚拟机指令用来操作 boolean 类型。但是,对于有 boolean 值参与运行的表达式,都会被编译成 int 类型的数据。


虚拟机直接支持了 boolean 数组,它使用newarray指令来创建数组,并可以使用 baload 和 bastore 来访问和修改 boolean 类型的数组


在 Oracle 的Java虚拟机实现中, boolean 类型的数组被编码成和 byte类型的数组, 每个 boolean 元素使用 8 bit。

所以虚拟机规范是这样定义的:boolean 单独使用时,占 4 字节,在数组中使用时,占 1 字节。但最终如何实现,还是要看各个虚拟机厂商是否遵守规范了。

相关推荐

自己动手写Android数据库框架_android开发数据库搭建

http://blog.csdn.net/feiduclear_up/article/details/50557590推荐理由关于Android数据库操作,由于每次都要自己写数据库操作,每次还得去...

谷歌开源大模型评测工具LMEval,打通谷歌、OpenAI、Anthropic

智东西编译|金碧辉编辑|程茜智东西5月28日消息,据科技媒体TheDecoder5月26日报道,当天,谷歌正式发布开源大模型评测框架LMEval,支持对GPT-4o、Claude3.7...

工信部:着力推动大模型算法、框架等基础性原创性的技术突破

工信部新闻发言人今日在发布会上表示,下一步,我们将坚持突出重点领域,大力推动制造业数字化转型,推动人工智能创新应用。主要从以下四个方面着力。一是夯实人工智能技术底座。通过科技创新重大项目,着力推动大模...

乒乓反复纠结“框架不稳定”的三个小误区

很多球友由于对框架的认知不清晰,往往会把“框架不稳定”当成一种心理负担,从而影响学球进度,其典型状态就是训练中有模有样,一旦进入实战,就像被捆住了手脚。通过训练和学习,结合“基本功打卡群”球友们交流发...

前AMD、英特尔显卡架构师Raja再战GPU,号称要全面重构堆栈

IT之家8月5日消息,知名GPU架构师拉贾科杜里(RajaKoduri)此前曾先后在AMD和英特尔的显卡部门担任要职。而在今日,由Raja创立的GPU软件与IP初创企...

三种必须掌握的嵌入式开发程序架构

前言在嵌入式软件开发,包括单片机开发中,软件架构对于开发人员是一个必须认真考虑的问题。软件架构对于系统整体的稳定性和可靠性是非常重要的,一个合适的软件架构不仅结构清晰,并且便于开发。我相...

怪不得别人3秒就知道软考案例怎么做能50+

软考高级统一合格标准必须三科都达到45分,案例分析也一直是考生头疼的一门,但是掌握到得分点,案例能不能50+还不是你们说了算吗?今天就结合架构案例考点,分享实用的备考攻略~一、吃透考点,搭建知识框架从...

UML统一建模常用图有哪些,各自的作用是什么?一篇文章彻底讲透

10万+爆款解析:9大UML图实战案例,小白也能秒懂!为什么需要UML?UML(统一建模语言)是软件开发的“蓝图”,用图形化语言描述系统结构、行为和交互,让复杂需求一目了然。它能:降低沟通成本避...

勒索软件转向云原生架构,直指备份基础设施

勒索软件组织和其他网络犯罪分子正越来越多地将目标对准基于云的备份系统,对久已确立的灾难恢复方法构成了挑战。谷歌安全研究人员在一份关于云安全威胁演变的报告中警告称,随着攻击者不断改进数据窃取、身份泄露和...

ConceptDraw DIAGRAM:释放创意,绘就高效办公新未来

在当今数字化时代,可视化工具已成为提升工作效率和激发创意的关键。ConceptDrawDIAGRAM,作为一款世界顶级的商业绘图软件,凭借其强大的功能和用户友好的界面,正逐渐成为众多专业人士的首选绘...

APP 制作界面设计教程:一步到位_app界面设计模板一套

想让APP界面设计高效落地,无需繁琐流程,掌握“框架搭建—细节填充—体验优化”三步法,即可一步到位完成专业级设计。黄金框架搭建是基础。采用“三三制布局”:将屏幕横向三等分,纵向保留三...

MCP 的工作原理:关键组件_mcp部件

以下是MCP架构的关键组件:MCP主机:像ClaudeDesktop、GitHubCopilot或旅行助手这样的AI智能体,它们希望通过MCP协议访问工具、资源等。MCP主机会...

软件架构_软件架构师工资一般多少

软件架构师自身需要是程序员,并且必须一直坚持做一线程序员。软件架构应该是能力最强的一群程序员,他们通常会在自身承接编程任务的同时,逐渐引导整个团队向一个能够最大化生产力的系统设计方向前进。软件系统的架...

不知不觉将手机字体调大!老花眼是因为“老了吗”?

现在不管是联系、交友,还是购物,都离不开手机。中老年人使用手机的时间也在逐渐加长,刷抖音、看短视频、发朋友圈……看手机的同时,人们也不得不面对“视力危机”——老花眼,习惯眯眼看、凑近看、瞪眼看,不少人...

8000通用汉字学习系列讲座(第046讲)

[表声母字]加(续)[从声汉字]伽茄泇迦枷痂袈笳嘉驾架咖贺瘸(计14字)嘉[正音]标准音读jiā。[辨形]上下结构,十四画。会意形声字,从壴从加,加也表声。注:从壴,字义与鼓乐有关;从加,字义与...

取消回复欢迎 发表评论: