为啥我不能添加两个字节并获得一个 int,而我可以添加两个最终字节获得一个字节?
Posted
技术标签:
【中文标题】为啥我不能添加两个字节并获得一个 int,而我可以添加两个最终字节获得一个字节?【英文标题】:Why can not I add two bytes and get an int and I can add two final bytes get a byte?为什么我不能添加两个字节并获得一个 int,而我可以添加两个最终字节获得一个字节? 【发布时间】:2012-10-17 11:48:25 【问题描述】: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,即使两个字节的总和适合一个字节。
为什么当我们添加两个适合一个字节的最终字节时会发生这种情况? 没有编译器错误。
【问题讨论】:
【参考方案1】:From the JLS 5.2 Assignment Conversion
此外,如果表达式是 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 没有看到错误,因为他幸运地选择了总和以适合一个字节的值。 @Aubin 感谢添加摘要和详细说明 但允许添加两个 int 类型。即使在 int 类型的情况下,也可能发生溢出,对吗?为什么 int 和 byte 类型的行为不同? 还有,"A compile-time constant expression is an expression […] composed using only the following: • Literals of primitive type and literals of typeString
. […] • The additive operators +
and -
. […] • Simple names that refer to constant variables.""A variable of primitive type or type String
, that is final
and initialized with a compile-time constant expression, is called a constant variable."。
@Rajesh 因为 java 中的二进制操作 (+) 将返回整数。您可能需要显式转换 byte c = (byte) (a + b);或将这些字节字段声明为 final。但是,+= 运算符会为您执行强制转换。比如说,如果你有字节 a = 2, b = 3;然后 (a += b) 按预期给你 5,既不需要显式转换也不需要'final'。【参考方案2】:
byte z = x + y; // x and y are declared final
这里,由于x
和y
被声明为final
,所以RHS
上的表达式值在编译时是已知的,固定为(1 + 2 = 3)
并且不能变化。所以,你不需要明确地进行类型转换
byte c = a + b; // a and b are not declared final
然而,在这种情况下,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`
【讨论】:
如果 x = 120 和 y = 120 会追加什么? @Aubin。在这种情况下,它会失败。因为 240 不能容纳在字节中。【参考方案3】:每当我们在两个变量 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 的类型)
最大(整数,字节,字节)
结果是类型:int,找到的是int,但需要在字节中
所以我们需要要求类型转换为字节
byte a=10;
byte b=20;
byte c=(byte) (a+b);
【讨论】:
您能解释一下为什么我们必须将 a,b 的总和转换为字节为byte c=(byte) (a+b);
,为什么会抛出错误? byte c=(a+b);
?以上是关于为啥我不能添加两个字节并获得一个 int,而我可以添加两个最终字节获得一个字节?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能腌制一个 typing.NamedTuple 而我可以腌制一个 collections.namedtuple?
c语言char和int可以互相赋值,但指针不能赋值,char *和int *不能直接赋值,为啥呢?谢谢