Java基本數據類型轉換

一:Java的基本數據類型和引用數據類型sql

1:基本數據類型架構

2:引用數據類型併發

二:基本數據的類型轉換jvm

基本數據類型中,布爾類型boolean佔有一個字節,因爲其自己所代碼的特殊含義,boolean類型與其餘基本類型不能進行類型的轉換(既不能進行自動類型的提高,也不能強制類型轉換), 不然,將編譯出錯。分佈式

1.基本數據類型中數值類型的自動類型提高ide

數值類型在內存中直接存儲其自己的值,對於不一樣的數值類型,內存中會分配相應的大小去存儲。如:byte類型的變量佔用8位,int類型變量佔用32位等。相應的,不一樣的數值類型會有與其存儲空間相匹配的取值範圍。具體以下所示:高併發

圖中依次表示了各數值類型的字節數和相應的取值範圍。在Java中,整數類型(byte/short/int/long)中,對於未聲明數據類型的×××,其默認類型爲int型。在浮點類型(float/double)中,對於未聲明數據類型的浮點型,默認爲double型。性能

接下來咱們看看以下一個較爲經典例子:學習

複製代碼
1 package com.corn.testcast;
2
3
4 public class TestCast {
5
6 public static void main(String[] args) {
7 byte a = 1000; // 編譯出錯 Type mismatch: cannot convert from int to byte
8 float b = 1.5; // 編譯出錯 Type mismatch: cannot convert from double to float
9 byte c = 3; // 編譯正確
10 }
11
12 }
複製代碼
是否是有點奇怪?按照上面的思路去理解,將一個int型的1000賦給一個byte型的變量a,編譯出錯,提示"cannot convert from int to byte"是對的,1.5默認是一個double型,將一個double類型的值賦給一個float類型,編譯出錯,這也是對的。可是最後一句:將一個int型的3賦給一個byte型的變量c,竟然編譯正確,這是爲何呢?內存

緣由在於:jvm在編譯過程當中,對於默認爲int類型的數值時,當賦給一個比int型數值範圍小的數值類型變量(在此統一稱爲數值類型k,k能夠是byte/char/short類型),會進行判斷,若是此int型數值超過數值類型k,那麼會直接編譯出錯。由於你將一個超過了範圍的數值賦給類型爲k的變量,k裝不下嘛,你有沒有進行強制類型轉換,固然報錯了。可是若是此int型數值尚在數值類型k範圍內,jvm會自定進行一次隱式類型轉換,將此int型數值轉換成類型k。如圖中的虛線箭頭。這一點有點特別,須要稍微注意下。

在其餘狀況下,當將一個數值範圍小的類型賦給一個數值範圍大的數值型變量,jvm在編譯過程當中俊將此數值的類型進行了自動提高。在數值類型的自動類型提高過程當中,數值精度至少不該該下降(整型保持不變,float->double精度將變高)。

複製代碼
1 package com.corn.testcast;
2
3 public class TestCast {
4
5 public static void main(String[] args) {
6 long a = 10000000000; //編譯出錯: The literal 10000000000 of type int is out of range
7 long b = 10000000000L; //編譯正確
8 int c = 1000;
9 long d = c;
10 float e = 1.5F;
11 double f = e;
12 }
13
14 }
複製代碼
如上:定義long類型的a變量時,將編譯出錯,緣由在於10000000000默認是int類型,同時int類型的數值範圍是-2^31 ~ 2^31-1,所以,10000000000已經超過此範圍內的最大值,故而其自身已經編譯出錯,更談不上賦值給long型變量a了。

此時,若想正確賦值,改變10000000000自身默認的類型便可,直接改爲10000000000L便可將其自身類型定義爲long型。此時再賦值編譯正確。

將值爲1000的int型變量c賦值給long型變量d,按照上文所述,此時直接發生了自動類型提高, 編譯正確。同理,將e賦給f編譯正確。

接下來,還有一個地方須要注意的是:char型其自己是unsigned型,同時具備兩個字節,其數值範圍是0 ~ 2^16-1,由於,這直接致使byte型不能自動類型提高到char,char和short直接也不會發生自動類型提高(由於負數的問題),同時,byte固然能夠直接提高到short型。

2.基本數據類型中的數值類型強制轉換

當咱們須要將數值範圍較大的數值類型賦給數值範圍較小的數值類型變量時,因爲此時可能會丟失精度(1講到的從int到k型的隱式轉換除外),所以,須要人爲進行轉換。咱們稱之爲強制類型轉換。

首先咱們看一下以下的例子:

複製代碼
1 package com.corn.testcast;
2
3 public class TestCast {
4
5 public static void main(String[] args) {
6 byte p = 3; // 編譯正確:int到byte編譯過程當中發生隱式類型轉換
7 int a = 3;
8 byte b = a; // 編譯出錯:cannot convert from int to byte
9 byte c = (byte) a; // 編譯正確
10 float d = (float) 4.0;
11 }
12
13 }
複製代碼
byte p =3;編譯正確在1中已經進行了解釋。接下來將一個值爲3的int型變量a賦值給byte型變量b,發生編譯錯誤。這兩種寫法之間有什麼區別呢?

區別在於前者3是直接量,編譯期間能夠直接進行斷定,後者a爲一變量,須要到運行期間才能肯定,也就是說,編譯期間爲以防萬一,固然不可能編譯經過了。此時,須要進行強制類型轉換。

強制類型轉換所帶來的結果是可能會丟失精度,若是此數值尚在範圍較小的類型數值範圍內,對於整型變量精度不變,但若是超出範圍較小的類型數值範圍內,極可能出現一些意外狀況。

以下經典例子:

複製代碼
1 package com.corn.testcast;
2
3 public class TestCast {
4
5 public static void main(String[] args) {
6 int a = 233;
7 byte b = (byte) a;
8 System.out.println("b:" + b); // 輸出:-23
9 }
10
11 }
複製代碼
爲何結果是-23?須要從最根本的二進制存儲考慮。

233的二進制表示爲:24位0 + 11101001,byte型只有8位,因而從高位開始捨棄,截斷後剩下:11101001,因爲二進制最高位1表示負數,0表示正數,其相應的負數爲-23。

3.進行數學運算時的數據類型自動提高與可能須要的強制類型轉換

以下代碼:

複製代碼
1 package com.corn.testcast;
2
3 public class TestCast {
4
5 public static void main(String[] args) {
6 byte a = 3 + 5; // 編譯正常 編譯成 3+5直接變爲8
7 int b = 3, c = 5;
8 byte d = b + c; // 編譯錯誤:cannot convert from int to byte
9
10 byte e = 10, f = 11;
11 byte g = e + f; // 編譯錯誤 +直接將10和11類型提高爲了int
12 byte h = (byte) (e + f); //編譯正確
13 }
14
15 } 歡迎工做一到五年的Java工程師朋友們加入Java羣: 891219277
羣內提供免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、Spring源碼,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)合理利用本身每一分每一秒的時間來學習提高本身,不要再用"沒有時間「來掩飾本身思想上的懶惰!趁年輕,使勁拼,給將來的本身一個交代!

複製代碼當進行數學運算時,數據類型會自動發生提高到運算符左右之較大者,以此類推。當將最後的運算結果賦值給指定的數值類型時,可能須要進行強制類型轉換。

相關文章
相關標籤/搜索