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
答案 0 :(得分:16)
如果java支持byte数据类型,那么为什么对byte的操作会产生int
因为这就是Java虚拟机的设计方式。没有指令集对字节类型执行操作。相反,int
类型的指令集用于boolean
,byte
,char
和short
类型的操作。
编译器使用Java虚拟机指令对类型
byte
和short
的文字值进行加载,这些指令在编译时将这些值符号扩展为类型int
的值或运行 - 时间。类型boolean
和char
的文字值的加载使用在编译时或运行时将文字零扩展为类型int
的指令进行编码。 [..]。因此,对实际类型boolean
,byte
,char
和short
的值的大多数操作都是由对计算类型int
的值进行操作的指令正确执行的。
背后的原因也在该部分中指明:
鉴于Java虚拟机的单字节操作码大小,将编码类型编码到操作码会对其指令集的设计造成压力。如果每个类型化指令都支持所有Java虚拟机的运行时数据类型,则会有比
byte
中表示的指令多的指令。 [...]可以根据需要使用单独的指令在不支持和支持的数据类型之间进行转换。
有关所有指令集可用于各种类型的详细信息,您可以查看该部分中的表格。
还有一个表指定实际类型到JVM计算类型的映射:
答案 1 :(得分:12)
编译器正在做正确的事情。因为(a + b)可以超出可以保存在字节变量中的最大值。如果你告诉编译器a,b值不会改变,使用'final'关键字就不会再抱怨了。
final byte a = 1;
final byte b = 1;
byte c = a + b;
答案 2 :(得分:9)
JLS 5.6.2: Binary Numeric Promotion涵盖了它:
应用扩展基元转换(第5.1.2节)来转换以下规则指定的一个或两个操作数:
如果任一操作数的类型为
double
,则另一个操作数将转换为double
。否则,如果任一操作数的类型为
float
,则另一个操作数将转换为float
。否则,如果任一操作数的类型为
long
,则另一个操作数将转换为long
。否则,两个操作数都会转换为
int
类型。
答案 3 :(得分:0)
是的,这是语言规范。
添加(+)运算符。添加时,'a'
会转换(隐式强制转换)为int
类型,
b也可以输入int
。因此,result
隐式为int
类型。
同样适用于-
运营商。
答案 4 :(得分:0)
在对任何操作数进行算术运算时,结果以 MAX(int,operand1类型,operand2类型,... operandN类型)格式存储
例如:
byte a=10;
byte b=20;
byte c=a+b;
然后a + b的结果将以MAX(int,operand1类型,operand2类型,... operandN类型)的形式存储 在这种情况下 MAX(int,byte,byte)最大值是int,它是最大值,因此c将具有int值但c已被声明为byte,并且我们不能将int(更大)值存储到byte(更小)中。这同样适用于每个算术运算符。
这就是错误所说的原因 错误:不兼容的类型:从 int 到byte
的可能有损转换答案 5 :(得分:0)
编译器正确,将变量声明为final或强制转换为字节:
byte b = 1;
byte c = 22;
byte a = (byte) (b + c);
JAVA:字节+字节=整数
:)