|
|
|
Sponsored Link •
|
|
Advertisement
|
Type conversions
The Java virtual machine has many opcodes that convert from one primitive
type to another. No opcodes follow the conversion opcodes in the bytecode
stream. The value to convert is taken from the top of the stack. The JVM
pops the value at the top of the stack, converts it, and pushes the result
back onto the stack. Opcodes that convert between int, long, float, and
double are shown in the following table. There is an opcode for each possible
from-to combination of these four types:
| Opcode | Operand(s) | Description |
|---|---|---|
i2l |
(none) | converts int to long |
i2f |
(none) | converts int to float |
i2d |
(none) | converts int to double |
l2i |
(none) | converts long to int |
l2f |
(none) | converts long to float |
l2d |
(none) | converts long to double |
f2i |
(none) | converts float to int |
f2l |
(none) | converts float to long |
f2d |
(none) | converts float to double |
d2i |
(none) | converts double to int |
d2l |
(none) | converts double to long |
d2f |
(none) | converts double to float |
Opcodes that convert from an int to a type smaller than int are shown
in the following table. No opcodes exist that convert directly from a long,
float, or double to the types smaller than int. Therefore converting from
a float to a byte, for example, would require two steps. First the float
must be converted to an int with f2i, then the resulting int can
be converted to a byte with int2byte.
| Opcode | Operand(s) | Description |
|---|---|---|
int2byte |
(none) | converts int to byte |
int2char |
(none) | converts int to char |
int2short |
(none) | converts int to short |
Although opcodes exist that convert an int to primitive types smaller than int (byte, short, and char), no opcodes exist that convert in the opposite direction. This is because any bytes, shorts, or chars are effectively converted to int before being pushed onto the stack. Arithmetic operations upon bytes, shorts, and chars are done by first converting the values to int, performing the arithmetic operations on the ints, and being happy with an int result. This means that if you add 2 bytes you get an int, and if you want a byte result you must explicitly convert the int result back to a byte. For example, the following code won't compile:
class BadArithmetic {
byte addOneAndOne() {
byte a = 1;
byte b = 1;
byte c = a + b;
return c;
}
}
When presented with the above code, javac objects with the following remark:
BadArithmetic.java(7): Incompatible type for declaration. Explicit cast needed to convert int to byte.
byte c = a + b;
^
To remedy the situation, the Java programmer must explicitly convert the int result of the addition of a + b back to a byte, as in the following code:
class GoodArithmetic {
byte addOneAndOne() {
byte a = 1;
byte b = 1;
byte c = (byte) (a + b);
return c;
}
}
This makes javac so happy it drops a GoodArithmetic.class file, which contains the following bytecode sequence for the addOneAndOne() method:
iconst_1 // Push int constant 1.
istore_1 // Pop into local variable 1, which is a: byte a = 1;
iconst_1 // Push int constant 1 again.
istore_2 // Pop into local variable 2, which is b: byte b = 1;
iload_1 // Push a (a is already stored as an int in local variable 1).
iload_2 // Push b (b is already stored as an int in local variable 2).
iadd // Perform addition. Top of stack is now (a + b), an int.
int2byte // Convert int result to byte (result still occupies 32 bits).
istore_3 // Pop into local variable 3, which is byte c: byte c = (byte) (a + b);
iload_3 // Push the value of c so it can be returned.
ireturn // Proudly return the result of the addition: return c;
|
Sponsored Links
|