添加字节是由于java语言规则还是因为jvm而转换为int?

byte a = 1;
byte b = 1;
byte c = a + b;

抛出误差:可能损失精度

byte subt = a_s - a_b;
                ^
  required: byte
  found:    int

此行为是否与 jvm 有关,或者它是在 java 语言中定义的。

编辑:如果它是在java语言中定义的,那么它是否因为牢记jvm而这样做?

意味着如果java支持数据类型,那么为什么结果byteoperation on byteint


答案 1

如果java支持字节数据类型,那么为什么对字节的操作结果为int

因为这就是Java虚拟机的设计方式。没有对字节类型执行操作的指令集。相反,type 的指令集用于对 、 、 和 类型进行运算。intbooleanbytecharshort

来自 JVM 规范 - 第 2.11.1 节

编译器对类型的文本值的负载进行编码,并使用 Java 虚拟机指令将这些值签名扩展为编译时或运行时的类型值。加载类型的文本值,并使用在编译时或运行时将文本零扩展为类型的值的指令进行编码。[..].因此,对实际类型 、 、 和 的值的大多数操作都是由对计算类型的值进行操作的指令正确执行的。byteshortintbooleancharintbooleanbytecharshortint

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

考虑到 Java 虚拟机的单字节操作码大小,将类型编码为操作码会给其指令集的设计带来压力。如果每个类型化指令都支持 Java 虚拟机的所有运行时数据类型,则指令将比 .[...]根据需要,可以使用单独的指令在不受支持的数据类型和受支持的数据类型之间进行转换。byte

有关所有类型的所有指令集可用的详细信息,您可以浏览该部分中的表。

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


答案 2

JLS 5.6.2:二进制数字提升涵盖以下内容:

加宽基元转换 (§5.1.2) 应用于转换以下规则指定的任一或两个操作数:

  • 如果任一操作数的类型为 ,则另一个操作数将转换为 。doubledouble

  • 否则,如果任一操作数的类型为 ,则另一个操作数将转换为 。floatfloat

  • 否则,如果任一操作数的类型为 ,则另一个操作数将转换为 。longlong

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