java 類型轉換的原理

最近在看JDK的源碼,在看源碼的時候看到了0xff這麼個東東,從這裏引出了類型轉換。所以在此記錄下。java

在寫原理以前先看幾個例子。byte b=-1;int a=b;而後打印a得出的結果是-1.int b=-1;byte a=(byte)b;打印a得出來的是-1。int a=255;byte b=(byte)255;打印b得出的結果也是-1;而把這個強制轉出來的-1再轉回int,得出的確不是255了,有點奇怪了。這是爲何那?好了,廢話不過說,下面就開始討論爲何了。在講這個以前先來幾個概念。二進制中的原碼,反碼,補碼,補位,真值。再有就是byte類型和int類型分別佔了多少位。這裏須要說一下,二進制的高位是符號位,1表示負數,0表示正數。注:java是用補碼存儲數據的。框架

byte類型佔一個字節,一個字節由8位二進制組成,因此說byte類型佔了8位。int類型佔4個字節,因此說int類型佔了8位。學習

真值:這個就看字面意思,int a=-1;a的真值就是-1.spa

原碼:int類型的-1的二進制表示,因爲-1是負數,又是int類型的,因此他須要32個二進制來表示,二進制的最高位是符號位,因此爲1,1的二進制爲1,因此-1的二進制表示爲   1000 0000 0000 0000 0000 0000 0000 0001;源碼

反碼:正數的反碼就是原碼,負數的反碼是在原碼的基礎上,符號位不變,其他位取反。因此int類型的-1的反碼是基礎

1111 1111 1111 1111 1111 1111 1111 1111。原理

補碼:正數的補碼就是原碼,負數的補碼是在反碼的基礎上加1。因此,int類型的-1的補碼是 1111 1111 1111 1111 1111 1111 1111 1111。二進制

補位:補位是二進制中在擴充位數的時候,位數不夠須要在左邊補齊,補齊的方式爲若是是正數的補位,左邊所有補0,負數左邊所有補1(也就是說補位的時候補足的是符號位)。方法

進入正題:數據

int a=-1;byte b=(byte)a;b的結果是-1。爲何int類型給byte類型賦值的時候爲何須要作強制類型轉換,由於int類型是32位的,而byte類型只有8位,8位沒法存儲32位,因此須要把32位強制轉爲8位。這個結果是怎麼得出來的呢?從二進制的角度開始分析,int類型的-1的補碼是 1111 1111 1111 1111 1111 1111 1111 1111。他在強制轉爲8位byte的時候須要把高24位丟棄,只保留8位,也就是 1111 1111 ,這8位是補碼的形式,轉化爲原碼,8位的最高位是1.因此是負數。根據原碼,反碼和補碼的計算方法能夠得出他的反碼是1111 1110 ,原碼是 1000 0001 ,因此他的真值是-1。

byte a =-1,int b=a,b的結果是-1。爲何byte類型給int類型賦值的時候不須要作強制類型轉換,由於是從低位向高位轉,會自動補位。byte類型的-1的原碼是1000 0001 ,他的補碼就是1111 1111 。因爲byte類型須要從8位轉爲32位的int類型,位數不夠,根據擴充原則須要在二進制原碼的左邊擴充符號位。注意,byte類型的-1的原碼的補位後的結果不是1111 1111 1111 1111 1111 1111 1000 0001 ,而是1000 0000 0000 0000 0000 0000 0000 0001 。緣由是在補位的時候是先將真值取絕對值,計算出他的原碼,將原碼擴充完畢以後,最高位改成符號。所以,byte類型的-1的絕對值是1,他的原碼是0000 0001 ,補全32位須要在左邊補24個0,補完以後因爲是負數的補位,因此將最高位的符號位改成1,表示負數,因此byte類型的-1擴充爲int類型後他的原碼是1000 0000 0000 0000 0000 0000 0000 0001 。(其實根據補碼補位也是能夠的,byte 類型-1 的補碼是1111 1111 ,他補位以後,由於最高位是負數,因此左邊所有補充1 ,爲1111 1111 1111 1111 1111 1111 1111  1111 ,這是補碼,最高位符號位不變,他的反碼是1111 1111 1111 1111 1111 1111 1111  1110,原碼就是 1000 0000 0000 0000 0000 0000 0000 0001  )因此,他的真值就是-1了。

再看最後一個例子,int a=255;byte b=(byte)a;b的值爲何是-1那?int類型的255的原碼是0000 0000 0000 0000 0000 0000 1111 1111,反碼是0000 0000 0000 0000 0000 0000 1111 1111,補碼是0000 0000 0000 0000 0000 0000 1111 1111。32位轉8位須要丟掉高24位,剩下1111 1111八位。剩下的八位的最高位是符號位,將他轉爲原碼就是1000 0001,真值就是-1了。

你們在本身算一下(byte)234的結果是什麼,而後在IDE裏在運行下看和本身手寫算出來的同樣嗎。


語文水平不太好,寫的可能有點囉嗦,但願你能理解下,寫這篇文章就是想和你們分享下在學習當中遇到的問題,怎麼解決的,學習java不是學習下框架什麼的就能夠了,只有瞭解底層的原理,在看別人寫的代碼才能真正理解。才能真正學會java,而不是感到迷茫。在此要感謝我親愛的媳婦,前面那些都是她幫我打字的,這麼晚了還要讓她陪我熬夜,好感動!

相關文章
相關標籤/搜索