Java開發筆記(七)強制類型轉換的風險


編碼過程中,不但能將數字賦值給某個變量,還能將一個變量賦值給另一個變量。比如下面代碼把整型變量changjiang賦值給整型變量longRiver:

		// 長江的長度為6397千米
		int changjiang = 6397;
		System.out.println("changjiang="+changjiang);
		int longRiver = changjiang; // 把一個整型變量賦值給另一個整型變量
		System.out.println("longRiver="+longRiver);

 

運行上面的測試代碼,發現兩個整型變量的數值一模一樣。

同類型的變量之間互相賦值完全沒有問題,麻煩的是給不同類型的變量賦值。要是把整型變量賦值給長整型變量,則發現編譯器直接提示錯誤,此時需要在原變量前面添加“(新類型)”表示強制轉換類型。改寫后的變量賦值語句就變成了下面這樣:

		// 不同類型的變量相互賦值,需要在原變量前面添加“(新類型)”表示強制轉換類型
		long longRiver = (long) changjiang; // 把整型變量賦值給長整型變量

 

然而,不同類型的變量相互賦值是有風險的,尤其是把高精度的數字賦值給低精度的數字,例如將八字節的長整型數強制轉成四字節的整型數,結果只有低位的四個字節保留了下來,而高位的四個字節被舍棄掉了。下面做個實驗,先用長整型變量保存世界人口的數量74億,再把該長整型變量賦值給整型變量,具體代碼如下所示:

		// 截至2018年元旦,世界人口大約有74億
		long worldPopulation = 7444443881L;
		System.out.println("worldPopulation="+worldPopulation);
		// 把長整型數賦值給整型數會丟失前四個字節
		int shijierenkou = (int) worldPopulation; // 把長整型數強制轉成整型數
		System.out.println("shijierenkou="+shijierenkou);

 

運行以上的實驗代碼,打印出來的變量值見以下日志:

worldPopulation=7444443881
shijierenkou=-1145490711

 

可見長整型數強制轉成整型數,結果整個數值都變掉了。

既然整數之間強制轉換類型存在問題,小數之間的類型強制轉換也不例外。倘若把雙精度數強制轉換成浮點數,數字精度也會變差。接下來仍然通過實驗進行觀察,以常見的圓周率為例,它的密率是中國古代數學家祖沖之發現的,其數值為3.1415926,包括小數部分在內共有8位數字。由於double類型的數字精度達到15到16位,因此利用雙精度變量保存圓周密率完全沒有問題。但是如果將這個密率的雙精度變量賦值給浮點變量,又會發生什么情況?下面的代碼就演示了把雙精度數強制轉成浮點數的場景:

		// 3.1415926是中國古代數學家祖沖之求得的圓周率數值,又稱祖率
		double zulv = 3.1415926;
		System.out.println("zulv="+zulv);
		// 把雙精度數賦值給浮點數會丟失數值精度
		float pai = (float) zulv; // 把雙精度數強制轉成浮點數
		System.out.println("pai="+pai);

 

運行上述實驗代碼,日志打印的變量值見下:

zulv=3.1415926
pai=3.1415925

 

可見浮點變量保存的密率數值變成了3.1415925,與雙精度變量相比,末尾的6變為5。之所以密率數值發生變化,是因為float類型的數字精度只有6到7位,而前述密率的總位數達到8位,顯然超出了float類型的精度范圍,使得強轉之后的浮點變量損失了范圍外的精度。

除了整數之間互轉、小數之間互轉以外,還有整數轉小數和小數轉整數的情況,可是整數與小數互轉依然存在數值虧損的問題。譬如一個雙精度變量賦值給一個整型變量,由於整型變量沒有空間保存小數部分,因此原本雙精度變量在小數點后面的數字全被舍棄。以下代碼就示范了這種數字類型轉換的例子:

		double jiage = 9.9;
		System.out.println("jiage="+jiage);
		// 把小數賦值給整型變量,會直接去掉小數點后面部分,不會四舍五入
		int price = (int) jiage; // 把雙精度數強制轉成整型數
		System.out.println("price="+price);

 

運行以上的測試代碼,日志打印結果如下:

jiage=9.9
price=9

 

果然整型變量丟掉了雙精度變量的小數部分,由此可見,不同類型之間的變量互轉問題多多,若非必要,一般不進行兩個變量的類型強制轉換操作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM