Java 原始數據類型轉換

在開發中經常遇到數據類型轉換的問題,大多數都是拿來強制轉換,強制轉換可能會出現你意想不到的問題:

int a = -1;

我們經過多重轉換之後:int b = (int)(char)(byte) a ;

System.out.println(b);

預計結果還會是-1嗎?

打印結果:65535

我們來分析下原因:

Java使用基於2的補碼的二進制運算,因此int類型的數值-1的所有32都是置位的;

1、int——>byte  轉型很簡單,它執行了一個窄化原始類型轉化,直接將除8位之外的所有位幹掉,留下的是一個8位都被置位了的byte,它仍舊錶示-1;

2、byte——>char 因爲byte是一個有符號類型,而char是個無符號類型,將一個整數類型轉換爲另一個寬度更寬的整數類型時,通常是保持其數值,但是卻不能將一個負的byte數值表示成一個char,因此,從byte到char轉換被認爲不是一個拓展原始類型的轉換,而是一個拓展並窄化原始類型的轉換:所有byte先轉換成int,int又被轉換成char。

這聽起來感覺有點繞,簡單的說:從較窄的整形轉換成較寬的整型時的符號擴展行爲:如果最初的數值類型是有符號的。那麼執行符號擴展;如果他是char,那麼不管它將要被轉換成什麼類型,都被執行零擴展。

所以byte數值-1轉換成char時,會發生符號擴展,作爲結果的char數值的16個位都被置位了。因此它等於216-1,即65535,從char到int的轉型也是一個拓展原始類型轉換,,它將執行零擴展而不是符號擴展,作爲結果的int數值也就是是65535.

(char是僅有的無符號整形)

如果你將一個char數值 c 轉換成一個寬度更寬的類型,並且你不希望有符號擴展,那麼可慮使用一個位掩碼“

int i = c & 0xffff;

或者用語句直接標明:

int i = c;//不會執行符號擴展


如果你將一個char數值 c 轉換轉換爲一個寬度更寬的整型,並且你希望有符號擴展,那麼就先將char轉型爲一個short,它與char具有同樣的寬度,但是它是有符號的:

int i = (short)c;//轉型將引起符號擴展


如果你將一個byte數值 b 轉型爲一個char。並且你不希望有符號擴展,那麼你必須使用一個位掩碼來限制它,通用做法:

char c = (char)(b & 0xff);


如果你將一個byte數值 b 轉型爲一個int,將一個整數類型轉換爲另一個寬度更寬的整數類型:

int i = (int)b & 0xFF

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章