为什么我不能将两个字节相加得到一个整数,而我可以将两个final字节相加得到一个字节?

34
public class Java{
    public static void main(String[] args){
        final byte x = 1;
        final byte y = 2;
        byte z = x + y;//ok
        System.out.println(z);

        byte a = 1;
        byte b = 2;
        byte c = a + b; //Compiler error
        System.out.println(c);
    }
}
如果表达式中涉及的所有 int 或更小类型的值之和可以用 int 类型表示,那么即使两个字节的和适合一个字节,结果也始终是 int 类型。 为什么当我们添加两个适合一个字节的最终字节时会发生这种情况? 编译器没有报错。
3个回答

34

来自JLS 5.2赋值转换

此外,如果表达式是类型为byte、short、char或int的常量表达式(§15.28): - 如果变量的类型是byte、short或char,并且常量表达式的值可以表示为变量的类型,则可以使用缩小的原始类型转换。

简而言之,表达式的值(因为它是常量表达式,在编译时已知)可在字节类型的变量中表示。

考虑您的表达式

 final byte x = 1;
 final byte y = 2;
 byte z = x + y;//This is constant expression and value is known at compile time

因为总和适合于字节,所以它不会引发编译错误。

现在,如果您执行

final byte x = 100;
final byte y = 100;
byte z = x + y;// Compilation error it no longer fits in byte

因此,总之,OP没有看到错误,是因为他幸运地选择了能够在一个字节内相加的值。 - Duncan Jones
@Aubin 谢谢,已添加摘要和详细描述。 - Amit Deshpande
2
但是,两个int类型之间的加法是被允许的。即使在int类型的情况下,溢出也可能会发生,对吗?为什么int类型和byte类型的行为不同呢? - Rajesh
1
@Rajesh 因为Java中的二进制操作(+)会返回整数。您可能需要显式转换字节c =(byte)(a + b);或声明这些字节字段为final。但是,+=运算符会为您执行转换。比如,如果您有byte a = 2,b = 3;那么(a + = b)将按预期给您5,不需要显式转换或“final”。 - Václav

10
byte z = x + y;  // x and y are declared final

在这里,由于xy被声明为final,因此在编译时可以确定RHS上的表达式的值,在计算时它是固定的,为(1 + 2 = 3),不会变化。所以,你不需要显式地进行类型转换。

byte c = a + b;   // a and b are not declared final

在这种情况下,ab的值没有被声明为final。因此,表达式的值在编译时未知,而是在运行时计算的。因此,您需要进行显式转换。


然而,即使在第一个代码中,如果a + b的值超出了范围-128到127,它也将无法编译。

final byte b = 121;
final byte a = 120;
byte x = a + b;  // This won't compile, as `241` is outside the range of `byte`

final byte b1 = 12;
final byte a1 = 12;
byte x1 = a1 + b1;  // Will Compile. byte can accommodate `24`

如果x = 120,y = 120会发生什么? - Aubin
1
在这种情况下,它会失败。因为240无法容纳在字节中。 - Rohit Jain

2
无论何时我们在两个变量a和b之间执行任何算术运算,结果总是:
max(int, type of a, type of b)

byte a=10;
byte b=20;
byte c=a+b(C.E )

解释:如上所述 max(int,a的类型,b的类型)

max(int,byte,byte)

结果的类型为:int,但发现为int,需要转换为byte类型

因此我们需要进行类型转换为byte

    byte a=10;
    byte b=20;
    byte c=(byte) (a+b);

请问为什么我们必须将a,b的和强制转换为byte类型并写为byte c=(byte) (a+b);,而不是直接写成byte c=(a+b);这样会报错? - GD- Ganesh Deshmukh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接