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. 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. If Java does the casting implicitly, why does c=b*2
report an error? 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). Therefore, why does byte f=(byte)128
return -128
? Since 128 % 256 = 128
, so what I expect is f=128
, but it returns -128
. Why? Thanks a lot.
This is because 50*2;
will be resolved at compile time while b*2;
will be resolved at runtime. So, at compile time Java compiler is sure that result of 50*2;
will be 100. But in case of 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.
You can use javap -v Test.class
to verify the same. 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. 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.
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
.
On the other hand, 258
is 0........01000000010
, and when you take the low 8 bits you get 00000010
, which is 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. To handle this kind of problem, Java automatically promotes each byte
, short
or char
operand to int
when evaluating an expression.
This means that the subexpression a*b
is performed using integers—not bytes. Thus, 2,000, the result of the intermediate expression, 50 * 40, is legal even though a and b are both specified as type byte.
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. However, because the operands were automatically promoted to int
when the expression was evaluated, the result has also been promoted to 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
.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.