为什么我不能添加两个字节并得到一个int,我可以添加两个最后的字节得到一个字节?

Joe*_*Joe 27 java int scjp variable-assignment ocpjp

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果涉及任何int-sized或者更小的表达式的结果总是为int,即使两个字节的总和适合一个字节.

当我们添加两个适合字节的最终字节时,为什么会这样? 没有编译器错误.

Ami*_*nde 30

来自JLS 5.2分配转换

此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节): - 如果变量的类型是byte,short或char,则可以使用缩小的原语转换,并且值常量表达式的变量可以表示在变量的类型中.

简而言之,表达式的值(在编译时已知,因为它是一个常量表达式)可以在byte的变量类型中表示.

考虑你的表达

 final byte x = 1;
 final byte y = 2;
 byte z = x + y;//This is constant expression and value is known at compile time
Run Code Online (Sandbox Code Playgroud)

因此,当求和适合字节时,它不会引发编译错误.

如果你这样做了

final byte x = 100;
final byte y = 100;
byte z = x + y;// Compilation error it no longer fits in byte
Run Code Online (Sandbox Code Playgroud)

  • 但是允许添加两个 int 类型。即使在 int 类型的情况下,也可能发生溢出,对吗?为什么 int 和 byte 类型的行为不同? (2认同)

Roh*_*ain 9

byte z = x + y;  // x and y are declared final
Run Code Online (Sandbox Code Playgroud)

这里,因为x和y声明final所以表达式的值RHS在编译时是已知的,它固定在(1 + 2 = 3)并且不能变化.因此,您不需要明确地对其进行类型转换

byte c = a + b;   // a and b are not declared final
Run Code Online (Sandbox Code Playgroud)

然而,在这种情况下,价值a和b未被宣布为最终.因此,表达式的值在编译时是未知的,而是在运行时计算.所以,你需要做一个明确的演员表.


但是,即使在第一个代码中,如果值a + b超出范围-128 to 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`
Run Code Online (Sandbox Code Playgroud)