1. 程式人生 > >兩小無猜的愛恨情仇--java =+和+=揭祕

兩小無猜的愛恨情仇--java =+和+=揭祕

故事背景

  當一個人問另一個人“敢不敢”的時候,另一個人必須說“敢”,這就是遊戲的規則。小男孩朱利安和小女孩蘇菲的相遇即開始於這樣一場孩童的鬧劇,一個精美的鐵盒子就是他們遊戲的見證。說髒話,擾亂課堂,在校長室小便,內衣外穿,一個遊戲兩人一玩十多年,他們什麼都敢,除了承認彼此相愛。

蘇菲(瑪麗昂·歌迪亞飾)提議兩人分別十年,挑戰的內容是朱利安(吉約姆·卡內飾)敢不敢傷害蘇菲。恍惚十年逝去,朱利安找到蘇菲,為了遊戲的進行他決定另娶她人,邀請蘇菲做伴娘。受到傷害的蘇菲在朱利安的婚禮上丟擲鐵盒子“你敢悔婚麼?”原本最最親密的朋友相互傷害最深。同樣心痛的兩個人相約再次分別十年。

十年裡,朱利安擁有了一切,家庭、事業、朋友,只是沒了蘇菲宛如沒了心,原來喪失激情的生活這般索然無味。

終於十年過去,“Love me, if you dare...”。

 

java =+和+=揭祕

java有兩對關係密切的物件,=+和+=,許多程式設計師都會認為表示式(x += i)只是表示式(x =x + i)的簡寫方式,真的是這樣嗎?請看程式:

 public static void main(String[] args) {
 short x = 0;
 int i = 123456;
 x += i;
 System.out.println(x);
 }

這個程式的結果是什麼?

執行後結果是:

-7616

 

不急,來看下面的程式:

    public static void main(String[] args) {
        short x = 0;
        int i = 123456;
        i =x + i;
        System.out.println(i);
    }

結果如我們預期:

123456

探究原因

在jsl15.26中定義,=是簡單的賦值表示式,+=是複雜的賦值表示式,其中+=表示式滿足規則:A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.

(複合賦值操作符包括 +=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、^=和|=)Java 語言規範中講到,複合賦值 E1 op= E2 等價於簡單賦值E1 =(T)((E1)op(E2)),其中T 是E1 的型別,除非E1 只被計算一次。

舉例如下:

short x = 3;
x += 4.6;

等同於

short x = 3;
x = (short)(x + 4.6);

分析例一

 short x = 0;
 int i = 123456;
 x += i;

等同於

 short x = 0;
 int i = 123456;
 x =(short)(x+ i);

第一步,x+i結果是int,第二步是int轉short是窄化,會丟失精度。得到-7616就可以理解了

分析例二

        short x = 0;
        int i = 123456;
        i =x + i;

i是int型別,x是short型別,如果是x=x+i編譯不能通過,報錯:

Type mismatch: cannot convert from int to short

如果使用i=x+i則沒有問題,結果為12345

 

參考資料

【1】https://baike.baidu.com/item/%E4%B8%A4%E5%B0%8F%E6%97%A0%E7%8C%9C/1674468

【2】https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.26

【3】java解惑