Java中Byte与Short运算时转型问题

问题

在使用short和byte时,11可能会涉及到短整型和字节型运算,例如下面这段代码片段,两个部分都会编译器都会给出类型不兼容的提示。byte型和short型(包括Byte和Short类型对象)解决方法均为将返回类型强转回byte或short,或者干脆使用int接受计算结果。

问题可以总结为为什么byte和short型运算结果都是int类型。

byte b1 = 1;
byte b2 = 2;
byte b3 = b1 + b2; //编译器爆红

short s = 1;
s = s + 1;//编译器爆红

但byte和short运算时还有一种特殊情况,即使用自增等自运算时却不会爆红,程序可以通过编译。

short s = 1;
s++;//不会爆红

接下来通过查看Java字节码文件的方式分析问题。

原因

byte、short自运算为什么能通过编译

首先使用javap -c命令对下列代码进行反编译,首先分析为什么自运算能够通过编译

byte b = 1;
b++;

反编译结果如下(只摘取main方法部分):

public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: iload_1
       3: iconst_1
       4: iadd
       5: i2b
       6: istore_1
       7: return
}

在字节码的第4、5、6行可以明显看到,在变量b做完自增后使用了i2b将int型结果自动转回了byte型,随后才存储到局部变量表中。

也就是说,byte和short类型在自增运算时,JVM自动帮我们完成了类型强制转换的工作,所以可以正常通过编译。

为什么byte、short的运算结果会被转换为int型

字节码角度

仍然可以拿上文中的反编译结果做解释。

首先说明一下,在JVM指令集中,部分指令可以分为两个部分来开,即:类型|操作,例如反编译结果中第四行的iadd,见文知意即int add整型自增,相对应的还有其他数据类型的自增版本,比如ladd、fadd、dadd三种。

那么可以看见在反编译结果中,所有的指令都是以i做开头,也就是说从头至尾都byte类型的数据是在JVM中都是以int的形式做读取、保存、运算等操作,进而可以理解为什么使用byte和short类型运算时都需要强转。

指令集角度

了解了上述的内容后,不难产生一个疑问,即为什么不单独为byte和short类型单独做出一系列例如badd、sadd的操作呢?

这是因为Java虚拟机在设计时限制了操作码长度为一个字节,即只有0~255共256条操作码可供设计,由于指令集空间有限,byte和short这两种相对不常用的数据类型的部分运算存取操作都没有被设计,没有被设计的这部分操作实际运行时均将类型转换为int型后使用int操作代为执行(因为小范围转换为大范围,向上转型操作是安全的)。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

7rulyL1ar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值