20
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支持byte数据类型那么为什么operation on byte结果int

4

6 回答 6

25

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

因为这就是 Java 虚拟机的设计方式。没有指令集可以对字节类型执行操作。而是 type 的指令集用于intbooleanbytecharshort类型的操作。

来自JVM 规范 - 第 2.11.1 节

编译器对大量类型的文字值进行编码,byte并使用 Java 虚拟机指令在编译时或运行时short将这些值符号扩展为类型值。int加载类型的文字值,并使用在编译时或运行时将文字零扩展为类型值的boolean指令进行char编码。int[..]。boolean因此,对实际类型、bytechar和的值的大多数操作short都是由对计算类型 的值进行操作的指令正确执行的int

该部分还指定了这背后的原因:

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

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

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

于 2013-08-28T09:10:32.707 回答
13

JLS 5.6.2: Binary Numeric Promotion涵盖了它:

加宽原语转换(第 5.1.2 节)适用于转换以下规则指定的一个或两个操作数:

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

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

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

  • 否则,两个操作数都转换为 type int

于 2013-08-28T09:10:18.950 回答
12

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

final byte a = 1;
final byte b = 1;
byte c = a + b;
于 2013-08-28T09:12:51.023 回答
0

是的,这是语言规范。

加法(+)运算符。添加时,'a'将(隐式强制转换)转换为inttype, b 也转换为 type int。因此result是隐含的类型int

操作员也一样-

于 2013-08-28T09:07:15.890 回答
0

编译器是对的,将变量声明为final或强制转换为字节:

byte b =  1;
byte c =  22;
byte a = (byte) (b + c);

JAVA:字节+字节=整数

:)

于 2018-08-17T03:54:23.863 回答
-1

在对任何操作数进行算术运算时,结果以这种形式存储MAX(int,operand1 type,operand2 type,...operandN type) 例如: byte a=10; byte b=20; byte c=a+b;

那么 a+b 的结果将以 MAX(int,operand1 type,operand2 type,...operandN type) 的形式存储在这种情况下 MAX(int,byte,byte) 最大值是 int ,它是最大值,所以 c将具有 int 值,但 c 已被声明为 byte,我们不能将 int(较大)值存储到 byte(较小)中。这同样适用于每个算术运算符。

这就是为什么错误显示错误:不兼容的类型:可能有损从int到 byte的转换

于 2018-01-31T19:16:28.407 回答