Java基本型別轉換
Java虛擬機器包括許多進行基本型別轉換工作的操作碼,這些執行轉換工作的操作碼後面沒有運算元,轉換的值從棧頂斷獲得。Java虛擬機器從棧頂端彈出一個值,對它進行轉換,然後再把轉換結果壓入棧。
int、long、float、double 型別之間的相互轉換,針對這四種類型之間的每一種可能的型別轉換,都存在相應的操作碼
操作碼 |
運算元 |
說明 |
i2l |
(無) |
將int型別的值轉換為long類型別 |
i2f |
(無) |
將int型別的值轉換為float類型別 |
i2d |
(無) |
將int型別的值轉換為double類型別 |
l2i |
(無) |
將long型別的值轉換為int類型別 |
l2f |
(無) |
將long型別的值轉換為float類型別 |
l2d |
(無) |
將long型別的值轉換為double類型別 |
f2i |
(無) |
將float型別的值轉換為int類型別 |
f2l |
(無) |
將float型別的值轉換為long類型別 |
f2d |
(無) |
將float型別的值轉換為double類型別 |
d2i |
(無) |
將double型別的值轉換為int類型別 |
d2l |
(無) |
將double型別的值轉換為long類型別 |
d2f |
(無) |
將double型別的值轉換為float類型別 |
int資料型別向byte、char、short型別的轉換(把int型別轉化為比int型別佔據更小空間的資料型別),這些操作碼從運算元棧中彈出一個int型別值,將它轉化為能用byte,short或char型別描述的int型別值,然後再把這個轉換後的int型別值壓入棧。
操作碼 |
運算元 |
說明 |
i2b |
(無) |
將int型別值轉換為byte型別值 |
i2c |
(無) |
將int型別值轉換為char型別值 |
i2s |
(無) |
將int型別值轉換為short型別值 |
i2b指令將彈出的int型別值擷取為byte型別,然後再對其進行帶符號擴充套件,恢復成int型別壓入棧。
i2c指令將彈出的int型別值擷取為char型別,然後再對其進行零擴充套件,恢復成int型別壓入棧
i2s將彈出的int型別值擷取為short型別,然後再對其進行帶符號擴充套件,恢復成int型別壓入棧
java虛擬機器中沒有把long,float,double型別直接轉化為比int型別值佔據更小空間的資料型別轉換成int型別的操作碼。因此,把float轉化為byte需要兩個步驟:首先,float型別值必須通過f2i指令轉化為int型別值,然後,所得的int型別再通過i2b指令轉化為byte型別。
儘管有操作碼可以把int型別值轉換為比int型別值佔據更小空間的資料型別(byte,short和char),但並不存在執行相反方向轉換的操作碼,因為任何byte、char、short型別值在壓入棧的時候,就已經有效的轉換成int型別了,涉及到byte、char、short型別的運算操作首先都把這些值轉化成int型別,然後對int型別值進行運算,最後得到int型別的結果。
例如如下程式碼:
public class ConvertTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
byte a = 1;
byte b = 1;
byte c = (byte)(a + b);
}
}
用javap工具檢視其位元組碼指令:
Compiled from "ConvertTest.java"
public class ConvertTest extends java.lang.Object{
public ConvertTest();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_1 //常量1入棧
1: istore_1 //彈出棧頂元素存入位置為1的區域性變數
2: iconst_1 //常量1入棧
3: istore_2 //彈出棧頂元素存入位置為2的區域性變數
4: iload_1 //取出位置1的區域性變數的值入棧
5: iload_2 //取出位置2的區域性變數的值入棧
6: iadd //彈出棧頂兩個元素做加法,然後結果入棧
7: i2b //轉化成byte型別
8: istore_3 //彈出棧頂元素存入位置為3的區域性變數
9: return
}
java虛擬機器通過截短和帶符號擴充套件的方式,將int轉化為byte,long,int, short,byte型別的最高位(“符號位”)指出此int型別值是正還是負。如果符號位為0,值為正;如果符號位為1,值為負。byte型別的第7位為符號位,從int型別值轉換到byte型別的時候,第7位的值將會被拷貝到第8位到第31位,這樣就產生了一個int型別值,這個值與原來int型別值被轉換為byte型別值後所獲得的結果具有相同的數值。在執行完截短和帶符號擴充套件後,這個int型別變數中將容納一個有效的byte型別的值。