[英]Weird behaviour of byte in java
I have this code: 我有以下代码:
public class First
{
public static void main(String[] args)
{
byte b=50;
byte c=b*2; //Error
byte d=50*2; //d=100
byte e=(byte)258; //e=258%256;
byte f=(byte)128; //f=128%256;
}
}
byte
is first promoted to int
and then it is performed. byte
算术表达式都将首先提升为int
,然后再执行。 Therefore I expected d=50*2
to also report an error, because the result of 50*2
is an int
value and we are storing it in a byte
without any explicit type cast. d=50*2
也会报告错误,因为50*2
的结果是一个int
值,我们将其存储在一个byte
而没有任何显式类型转换。 If Java does the casting implicitly, why does c=b*2
report an error? c=b*2
报告错误? byte
variable,then I have to explicitly type cast it into byte
and the value that will be stored is the value modulo 256 (Size of byte). byte
变量范围内的值,则必须显式地将其强制转换为byte
并且将要存储的值是模256(字节大小)的值。 Therefore, why does byte f=(byte)128
return -128
? byte f=(byte)128
返回-128
? Since 128 % 256 = 128
, so what I expect is f=128
, but it returns -128
. 128 % 256 = 128
,所以我期望的是f=128
,但它返回-128
。 Why? Thanks a lot. 非常感谢。
This is because 50*2;
这是因为
50*2;
will be resolved at compile time while b*2;
将在编译时解析,而
b*2;
will be resolved at runtime. 将在运行时解决。 So, at compile time Java compiler is sure that result of
50*2;
因此,在编译时Java编译器确保结果为
50*2;
will be 100. But in case of b*2;
将为100。但是在
b*2;
情况下b*2;
, as you have also mentioned that result of arithmetic operation is int
, and compiler cannot be sure if result could exceed byte
limits, so it complains and wants you to make sure the things by casting or changing type. ,正如您还提到的,算术运算的结果为
int
,并且编译器无法确定结果是否可以超出byte
限制,因此它抱怨并希望您通过强制转换或更改类型来确保结果。
You can use javap -v Test.class
to verify the same. 您可以使用
javap -v Test.class
进行验证。 See below: 见下文:
public static void main(java.lang.String[]);
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: bipush 100
2: istore_1
3: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
6: iload_1
7: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
10: return
LineNumberTable:
line 4: 0
line 5: 3
line 6: 10
For your second question, @Eran has already explained using bit representation of 128 and 258, and you can read further from JLS §5.1.3. 对于第二个问题,@ Eran已经使用128和258的位表示进行了解释,您可以从JLS§5.1.3进一步阅读。 Narrowing Primitive Conversion
缩小原始转换
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
将有符号整数缩小为整数类型T会简单地丢弃除n个最低阶位以外的所有位,其中n是用于表示类型T的位数。除了可能丢失有关数值幅度的信息外, ,这可能导致结果值的符号与输入值的符号不同。
As for your second question, when you downcast a numeric type, the low bits of the input are used to initialize the output. 至于第二个问题,当您向下转换数字类型时,将使用输入的低位来初始化输出。
Therefore, the int
128
, whose binary representation is 0......010000000
becomes the byte 10000000
(you take the low 8 bits), which is -128
. 因此,其二进制表示形式为
0......010000000
的int
128
变为字节10000000
(取低8位),即-128
。
On the other hand, 258
is 0........01000000010
, and when you take the low 8 bits you get 00000010
, which is 2. 另一方面,
258
是0........01000000010
,当您采用低8位时,您将得到00000010
,即2。
In addition to assignments, there is another place where certain type conversions may occur: ie in expressions.
除分配外,还有其他可能发生某些类型转换的地方:即在表达式中。
To see why, consider the following. 要了解原因,请考虑以下内容。 In an expression, the precision required of an intermediate value will sometimes exceed the range of either operand.
在表达式中,中间值所需的精度有时会超出两个操作数的范围。
For example, examine the following expression: 例如,检查以下表达式:
byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c;
The result of the intermediate term a * b
easily exceeds the range of either of its byte operands. 中间项
a * b
很容易超出其任一字节操作数的范围。 To handle this kind of problem, Java automatically promotes each byte
, short
or char
operand to int
when evaluating an expression. 为了处理此类问题,Java在评估表达式时会自动将每个
byte
, short
或char
操作数提升为int
。
This means that the subexpression a*b
is performed using integers—not bytes. 这意味着子表达式
a*b
是使用整数而不是字节执行的。 Thus, 2,000, the result of the intermediate expression, 50 * 40, is legal even though a and b are both specified as type byte. 因此,即使a和b都指定为类型字节,中间表达式50 * 40的结果2,000也合法。
As useful as the automatic promotions are, they can cause confusing compile-time errors.
与自动升级一样有用,它们可能导致令人困惑的编译时错误。
For example, this seemingly correct code causes a problem: 例如,以下看似正确的代码会导致问题:
byte b = 50;
b = b * 2; // Error! Cannot assign an int to a byte!
The code is attempting to store 50 * 2, a perfectly valid byte
value, back into a byte
variable. 该代码正在尝试将50 * 2(一个完全有效的
byte
值)存储回byte
变量中。 However, because the operands were automatically promoted to int
when the expression was evaluated, the result has also been promoted to int
. 但是,由于在评估表达式时将操作数自动提升为
int
,因此结果也提升为int
。 Thus, the result of the expression is now of type int
, which cannot be assigned to a byte
without the use of a cast
. 因此,表达的结果现在类型是
int
,其不能被分配给一个byte
而无需使用的cast
。
This is true even if, as in this particular case, the value being assigned would still fit in the target type. 即使在这种特殊情况下,即使分配的值仍然适合目标类型,也是如此。 In cases where you understand the consequences of overflow, you should use an explicit cast, such as
如果您了解溢出的后果,则应使用显式强制转换,例如
byte b = 50;
b = (byte)(b * 2);
which yields the correct value of 100. 得出正确的值100。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.