型別轉換
型別轉換是將一個值從一種型別更改為另一種型別的過程。例如, 可以將String
型別的資料“457”轉換為數值型,也可以將任意型別的 資料轉換為String型別。 如果從低精度資料型別向高精度資料型別轉換,則永遠不會溢位, 並且總是成功的;而把高精度資料型別向低精度資料型別轉換時,則會 有資訊丟失,有可能失敗。 資料型別轉換有兩種方式,即隱式轉換與顯式轉換。
隱式型別轉換
從低階型別向高階型別的轉換,系統將自動執行,程式設計師無須進行任何操作。這種型別的轉換稱為隱式轉換。下列基本資料型別會涉及數 據轉換,不包括邏輯型別和字元型別。這些型別按精度從低到高排列的 順序為byte < short < int < long < float < double
。
int x = 5;
float y = x; // y = 5.0
隱式轉換也要遵循一定的規則,來解決在什麼情況下將哪種型別的 資料轉換成另一種型別的資料。表列出了各種資料型別隱式轉換的 一般規則。
編譯階段
在編譯階段,Java 編譯器會檢查 x
的型別,並且知道它是一個 int
型別的值。由於 float
型別可以表示比 int
型別更大的範圍,並且 float
型別具有更高的精度,所以編譯器允許這種型別的轉換而不需要顯式的型別轉換運算子。
執行階段
在執行時,當這段程式碼被執行時,JVM 會將 int
型別的值轉換為 float
型別。具體來說,這涉及到將 int
型別的 32 位整數值轉換為 float
型別的 32 位單精度浮點數格式。
這個轉換實際上是透過將整數值編碼為一個特殊的浮點數來完成的,其中整數被視為一個十進位制數,並且沒有小數部分。這意味著,對於任何整數值,只要它在 float
型別可表示的範圍內(即不超出 float
型別的最大值),這個轉換就是精確無誤的。
記憶體佈局
在記憶體中,x
是一個 32 位的整數,而 y
是一個同樣佔據 32 位但按照 IEEE 754 標準儲存的浮點數。當 x
的值被複制到 y
時,實際上發生了以下步驟:
- 讀取
x
的值。 - 將這個整數值解釋為一個浮點數,這意味著建立一個浮點數的內部表示形式,包括符號位、指數和尾數部分。
- 將轉換後的值儲存到
y
中。
由於 int
和 float
都是 32 位寬,因此這個轉換不會涉及額外的資料擴充套件或壓縮。但是需要注意的是,儘管 5
作為一個整數可以直接轉換為 5.0f
並且不會丟失任何資訊,但對於某些其他的 int
值,轉換到 float
可能會導致精度上的損失。
byte mybyte =127;//定義 byte 型變數 mybyte,並把允許的最大值賦給 mybyte
int myint = 150; //定義int型變數 myint,並賦值 150
float myfloat = 452.12f;//定義 float 型變數 myfloat,並賦值
char mychar = 10;//定義 char型變數 mychar,並賦值
double mydouble =45.46546;//定義 double 型變數,並賦值
//將運算結果輸出
System.out.println("byte 型與 float 型資料進行運算結果為:"+(mybyte+ myfloat));
System.out.println("byte 型與int型資料進行運算結果為:"+mybyte*myint);
System.out.println("byte 型與 char 型資料進行運算結果為:"+mybyte/mychar);
System.out.println("double 型與 char 型資料進行運算結果為:"+(mydouble +mychar));
mybyte
是一個byte
型別的值,而myfloat
是一個float
型別的值。由於float
型別的範圍和精度都大於byte
型別,因此byte
型別的值會被提升為float
型別,然後進行加法運算。最終的結果是一個float
型別的值。
mybyte
是一個byte
型別的值,而myint
是一個int
型別的值。byte
型別的值會被提升為int
型別,然後與int
型別的值進行乘法運算。最終的結果是一個int
型別的值。
mybyte
是一個byte
型別的值,而mychar
是一個char
型別的值。char
型別本質上是一個int
型別的值(16 位),因此byte
型別的值會被提升為int
型別,然後進行除法運算。最終的結果是一個int
型別的值。
mydouble
是一個double
型別的值,而mychar
是一個char
型別的值。char
型別的值會被提升為int
型別,然後int
型別的值會被進一步提升為double
型別,因為double
型別的範圍和精度都大於int
型別。最後,兩個double
型別的值進行加法運算,得到的結果也是一個double
型別的值。
顯示型別轉換
當把高精度的變數的值賦給低精度的變數時,必須使用顯式型別轉 換運算(又稱強制型別轉換)。
執行顯式型別轉換時,可能會導致精度損失。除boolean型別外, 其他基本型別都能以顯式型別轉換的方法實現轉換。
當把整數賦值給一個byte、short、int、long
型變數時,不可以 超出這些變數的取值範圍,否則必須進行強制型別轉換。例如: byte b = (byte)129
int num = 10;
System.out.println("整數值為: " + num);
//將int轉換為字串型別
String data = String.valueOf(num);
System.out.println("字串值為: " + data);
在這裡,我們使用了Java String類的valueOf()
方法將int型別變數轉換為字串。
int a =(int)45.23; //45
long y=(long)456.6F; //456
int b = (int)'d'; //100
在浮點數向整數型轉換的過程中,小數部分被丟棄了,因為 int
型別只能儲存整數部分。這個過程是不可逆的,資料丟失是強制轉換的常見問題。表示式強制轉換,記得給表示式也加上括號,否側計算機就會認為先強制轉換d,再和a相加。
double d = 9.99;
double a = 7.99;
int i = (int)(d + a); // 強制將表示式轉換為 int
System.out.println(i); // 輸出17
System.out.println((int)d+a); // 輸出 16.99
四捨五入可以使用Math.round()
方法。