byte加byte居然是int了

本文涉及的产品
应用实时监控服务-用户体验监控,每月100OCU免费额度
性能测试 PTS,5000VUM额度
应用实时监控服务-应用监控,每月50GB免费额度
简介: 为什么在Java中,byte加byte的结果不是byte,而是int?本文将带你从Java语言规范和JVM规范层面研究该问题。

问题现象

最近在看 Java 的基础知识时看到一个有意思的现象,在 Java 中两个 byte 相加之后的结果的类型变成 int 类型了:

byte a = 1;
byte b = 2;
b = a + b;

image

从Idea给的提示可以看到,两个 byte 类型相加的结果变成了 int 类型,不能赋值给一个 byte 类型变量。其实不只是 byte,包括:short、char 等类型执行运算之后的结果也变成 int 类型了,不再是参与运算之前的类型。

如果想要上述代码能够正常编译和运行,可以修改为如下的写法:

// 写法一
byte a = 1;
byte b = 2;
b = (byte) (a + b);

// 写法二(这种写法是上面写法的一种简化写法,具体可以见:https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26.2
byte a = 1;
byte b = 2;
b += a;

问题原理

首先根据 Java 语言规范的描述,在执行加法或者减法运算时,会对操作数进行类型提升

image (2)

在进行类型提升的时候,byte、short、char 类型都会提升为int类型,由于两个数都提升为了 int 类型,它们执行的运算结果自然而然也就是 int 类型的了。

image (3)

在 JVM 的操作数栈的一个单位长度是 32 位,因此为了把参与运算的数放到操作数栈中就必须对其进行扩展,同时我理解这里也是为了和局部变量表的单位相匹配,局部变量表的基本单位是槽位,一个槽位的宽度也是 32 位。

image (4)

image (5)

从字节码指令也可以说明这点,JVM 中基本上没有关于 byte 类型运算的字节码指令:
image (6)

相关文章
|
SQL Java 数据库连接
对于mybatis if标签对 byte int 等非字符串和字符串判断的问题
对于mybatis if标签对 byte int 等非字符串和字符串判断的问题
163 0
|
存储 Java
[java 基础知识] byte int 互转
[java 基础知识] byte int 互转
135 0
|
Java
java基本数据类型, byte: short: int: long: float: double: float和double有什么区别 boolean: ch
java基本数据类型, byte: short: int: long: float: double: float和double有什么区别 boolean: ch
281 0
java中整型数据(byte、short、int、long)溢出的现象及原理
java中整型数据(byte、short、int、long)溢出的现象及原理
|
网络协议 机器人 物联网
案例分享:Qt modbus485调试工具(读写Byte、Int、DInt、Real、DReal)(当前v1.3.0)
案例分享:Qt modbus485调试工具(读写Byte、Int、DInt、Real、DReal)(当前v1.3.0)
案例分享:Qt modbus485调试工具(读写Byte、Int、DInt、Real、DReal)(当前v1.3.0)
案例分享:Qt西门子PLC调试模拟工具(包含PLC上位机通讯,PLC服务器,读写Byte、Int、DInt、Real)(持续更新,当前v1.5.0)
案例分享:Qt西门子PLC调试模拟工具(包含PLC上位机通讯,PLC服务器,读写Byte、Int、DInt、Real)(持续更新,当前v1.5.0)
案例分享:Qt西门子PLC调试模拟工具(包含PLC上位机通讯,PLC服务器,读写Byte、Int、DInt、Real)(持续更新,当前v1.5.0)
|
存储 Java
java:int强制类型转换成byte
int 在java中是32位, byte是8位 原码:就是二进制码,最高位为符号位,0表示正数,1表示负数,剩余部分表示真值 反码:在原码的基础上,正数反码就是他本身,负数除符号位之外全部按位取反 补码:正数的补码就是自己本身, 负数的补码是在自身反码的基础上加1
java:int强制类型转换成byte
|
Java
Java中两个或多个byte数组合并及int类型转数组
Java中两个或多个byte数组合并及int类型转数组
443 0
|
Java 网络架构
[Java工具] 关于byte和int的转换
需求 单片机通过Socket发送过来类似 { 0xff,0x0c ,0x80...}的byte数组,根据协议分为unsigned char 和signed char两种类型。
1416 0