今天同悅姐學到了關於Java的復合賦值操作(+=)的一點小知識,記錄下,感謝悅姐的講解!
首先來看下面兩行代碼:
short s1 = 1; s1 = s1 + 1;
對於稍微有點Java經驗的人來說,這個是非常簡單的問題,他們肯定會說 這樣是無法通過編譯的。
首先,因為short類型是16位的,而int類型是32位的,在進行(s1+1) 運算時,自動將s1提升到32位,然后與i相加,
得到的結果是32位的,而此時s1=s1+1; 必然報錯,因為這樣會丟失2個字節的精度,這是不容許的。但是你可以執行強轉:
s1=(short)(s1+1); 這樣就沒問題了.
現在我們再看下面這兩行代碼:
short s1 = 1; s1 +=1;
許多程序員都會認為這里的表達式(s1 +=1)只是上面表達式(s1 = s1 + 1)的簡寫方式,至少以前我是這樣認為的。但是這並不十分准確。
這兩個表達式都被稱為賦值表達式。開頭那條語句使用的是簡單賦值操作符(=),而這里這條語句使用的是復合賦值操作(+=)。
Java語言規范中講到,復合賦值 E1 op= E2等價於簡單賦值E1 = (T)((E1)op(E2) 其中T是E1的數據類型,op為操作符.
這種類型轉換或者是一個恆等轉換,或者是一個窄化轉換.
換句話說,復合賦值表達式自動地將它們所執行的計算的結果轉型為其左側變量的類型。如果結果的類型與該變量的類型相同,那么這個轉型不會造成任何影響。然而,如果結果的類型比該變量的類型要寬,那么復合賦值操作符將悄悄地執行一個窄化原始類型轉換。
但是我們讓JVM自動的為我們進行窄化轉換這樣好嗎?我們來看下下面這個問題
short s1=Short.MAX_VALUE;//32767 s1+=1; System.out.println(s1);
你可能會認為結果是32768,但是你一運行就會發現它會打印出:-32768,此時你也許幡然醒悟,原來我們丟失了精度,所以我們在用復合
賦值操作(+=)的時候要特別注意,這時它會窄化原始類型轉換(即使會丟失精度)。