由于java语言规则或jvm,是否将字节转换为int?

Pra*_*eek 13 java byte operation type-conversion type-promotion

byte a = 1;
byte b = 1;
byte c = a + b;
Run Code Online (Sandbox Code Playgroud)

引发错误:可能会损失精度

byte subt = a_s - a_b;
                ^
  required: byte
  found:    int
Run Code Online (Sandbox Code Playgroud)

这种行为是与jvm有关还是在java语言中定义的.

编辑:如果它是用java语言定义然后这样做是因为记住jvm?

表示如果java支持byte数据类型,那么为什么会operation on byte产生结果int

Roh*_*ain 19

如果java支持byte数据类型,那么为什么对byte的操作会产生int

因为这就是Java虚拟机的设计方式.没有指令集对字节类型执行操作.而对于指令集int类型用于对操作boolean,byte,char,和short类型.

JVM规范 - 第2.11.1节:

编译器对类型的文字值进行加载,byteshort使用Java虚拟机指令int在编译时或运行时将这些值签名扩展为类型的值.加载类型的文字值,booleanchar使用int在编译时或运行时将文字零扩展为类型值的指令进行编码.[..].因此,实际的类型的值的大多数操作boolean,byte,char,和short正确地通过在计算类型的值操作说明进行int.

其背后的原因也在该部分中指定:

鉴于Java虚拟机的单字节操作码大小,编码类型到操作码会对其指令集的设计造成压力.如果每个类型化指令都支持所有Java虚拟机的运行时数据类型,则会有更多的指令,而不是在a中表示byte.[...]可以根据需要使用单独的指令在不支持和支持的数据类型之间进行转换.

有关所有指令集可用于各种类型的详细信息,您可以查看该部分中的表.

还有一个表指定实际类型到JVM计算类型的映射:


Dev*_*ked 13

编译器正在做正确的事情.因为(a + b)可以超出可以保存在字节变量中的最大值.如果你告诉编译器a,b值不会改变,使用'final'关键字它不会再抱怨了.

final byte a = 1;
final byte b = 1;
byte c = a + b;
Run Code Online (Sandbox Code Playgroud)

  • 复合运算符 (+=) 将结果转换为 b = (byte) (b + a); (2认同)

Duk*_*ing 10

JLS 5.6.2:二进制数字促销包括:

应用扩展基元转换(第5.1.2节)来转换由以下规则指定的一个或两个操作数:

  • 如果任一操作数是类型double,则另一个操作数转换为double.

  • 否则,如果任一操作数是类型float,则另一个操作数转换为float.

  • 否则,如果任一操作数是类型long,则另一个操作数转换为long.

  • 否则,两个操作数都将转换为类型int.