一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Java中a=a+b 與 a+=b區(qū)別 以及和類型轉(zhuǎn)換的關(guān)系

 Baruch 2017-09-05

很久之前學習過 a=a+b 和a+=b的一些區(qū)別,進來再次回想起來,發(fā)現(xiàn)理解的還不透徹,所以又查資料找文件重新學習了一番。

比較這兩種運算符的區(qū)別,可以有以下兩個方面的比較: 執(zhí)行效率和類型轉(zhuǎn)換。

首先說一下執(zhí)行效率問題

就單純的執(zhí)行這兩條語句,不考慮編譯器的優(yōu)化的話,a=a+b的執(zhí)行效率是低于a+=b的,因為它多進行了一步中間變量的操作,而且會多占用一個變量的空間。而Java編譯器默認對其進行了優(yōu)化,優(yōu)化之后兩條語句都當做 a+=b來執(zhí)行了,所以實際上是沒有任何卻別的。

其次說一下有關(guān)類型轉(zhuǎn)換的區(qū)別。

相信大家都碰到過這種情況:

public class Test {
 
 public static void main(String[] args){
  int a = 2;
  float b = 6;
  a+=b; //right
//  a=a+b; //error
  a=(int) (a+b); //right
 }
}

當使用a=a+b的時候,會拋出”Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from float to int“的異常,這是可以理解的,如果不使用(int)強制類型轉(zhuǎn)換的話,float 是不能直接復值給int 變量的。

我們將a=a+b注釋掉,javac編譯完之后,再使用反編譯軟件(例如XJad)打開Test.class文件,會發(fā)現(xiàn)源代碼被解析成這樣子:

public class Test
{

 public Test()
 {
 }

 public static void main(String args[])
 {
  int a = 2;
  float b = 6F;
  a = (int)((float)a + b);
  a = (int)((float)a + b);
 }
}

即a+=b進行了強制類型轉(zhuǎn)換,和 a=(int)((float)a+b)是等價的!

到這里我們就明白了為什么a=a+b會拋出異常了。

原因:在Java中,在基本類型進行算術(shù)運算的時候,會發(fā)生小字節(jié)類型向大字節(jié)類型轉(zhuǎn)換的現(xiàn)象。如圖中 int 類型和float類型進行加法運算時會將 a 先轉(zhuǎn)換為float類型,然后再和b相加。這樣結(jié)果類型變成了float類型,如果這時候試圖把float類型賦值給a時便會拋異常。

另外,對于short,byte,char 比int 字節(jié)數(shù)小的變量類型來說,運算結(jié)果會自動轉(zhuǎn)換為int類型,如

  byte a = 1 , b=2;
  b=a+b;

  byte a = 1;
  short b =2;
  b=a+b;

都會拋出”Exception in thread "main" java.lang.Error: Unresolved compilation problem: Type mismatch: cannot convert from int to byte“類似的異常,可以看出a+b結(jié)果變成了int類型。

這是由于Java編譯器會在編譯期或者運行期將byte和short類型的數(shù)據(jù)帶符號擴展為相應(yīng)的int類型數(shù)據(jù),將boolean和char類型數(shù)據(jù)零位擴展為相應(yīng)的int類型數(shù)據(jù)。因此,在處理boolean 、byte、short 和 char 類型的數(shù)組是,也會用相應(yīng)的int類型的字節(jié)碼指令來處理。因此,大多數(shù)對于上述類型數(shù)據(jù)的操作,實際上都是使用相應(yīng)的 int 類型作為運算類型。

如果是final 修飾的變量,進行運算的時候則不會出現(xiàn)類型轉(zhuǎn)換異常。

public class Test {
 final int d = 3; 
 public static void main(String[] args){
  final short  a = 1;
  final short  b =2;
  short c=a+b;
 }
}

編譯后使用反編譯軟件打開后,代碼被解析成了這樣:

public class Test
{

 final int d = 3;

 public Test()
 {
 }

 public static void main(String args[])
 {
  short a = 1;
  short b = 2;
  short c = 3;
 }
}

可以看到,對于final 修飾的基本類型的變量來說,他們之間的運算直接就被硬編碼成了直接賦值語句,連中間結(jié)果都沒有了,類型轉(zhuǎn)換的異常也就沒了。

此外,我們可以注意到,對于方法內(nèi)的final 變量 a , b 來說,編碼時被直接省略了。而Test 類的final 成員變量 d 依然保留著final 屬性。

所以說,是否使用final修飾方法中普通變量對JVM來說沒有區(qū)別!使用final修飾方法中普通變量主要是為了給Java前端編譯器(如javac)看的!也就是說方法中被final修飾的普通變量在前端編譯時被javac檢查并保證該變量不會在作用域內(nèi)被改變新值,但被編譯成字節(jié)碼后用于修飾方法中普通變量的final就已經(jīng)不存在了!說的再具體點就是你用或不用final修飾方法中普通變量而生成的字節(jié)碼文件(.class文件)沒有區(qū)別。

PS:對于final 修飾的類成員來說,由于其生命周期在對象銷毀之前,所以它占用的應(yīng)該是堆內(nèi)存。(這個不確定 --)

Java 9 的新特性發(fā)布 http://www./Linux/2014-08/105707.htm

Java編程思想(第4版) 中文清晰PDF完整版 http://www./Linux/2014-08/105403.htm

編寫高質(zhì)量代碼 改善Java程序的151個建議 PDF高清完整版 http://www./Linux/2014-06/103388.htm

Java 8簡明教程 http://www./Linux/2014-03/98754.htm

Java對象初始化順序的簡單驗證 http://www./Linux/2014-02/96220.htm

Java對象值傳遞和對象傳遞的總結(jié) http://www./Linux/2012-12/76692.htm

本文永久更新鏈接地址http://www./Linux/2014-09/106764.htm

linux

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    我要看日本黄色小视频| 91香蕉国产观看免费人人| 深夜福利欲求不满的人妻| 免费午夜福利不卡片在线 视频 | 91免费一区二区三区| 国产精品午夜视频免费观看 | 亚洲一区二区三区中文久久| 一区二区欧美另类稀缺| 欧美一本在线免费观看| 日韩精品一区二区毛片| 欧洲精品一区二区三区四区| 白白操白白在线免费观看| 亚洲欧美黑人一区二区| 欧美国产日韩变态另类在线看| 日韩成人h视频在线观看| 偷拍偷窥女厕一区二区视频| 亚洲国产成人久久一区二区三区| 国产一区二区三区四区免费| 精品午夜福利无人区乱码| 欧美精品一区二区水蜜桃| 欧美大胆女人的大胆人体| 婷婷开心五月亚洲综合| 精品国产91亚洲一区二区三区| 亚洲国产精品久久琪琪| 绝望的校花花间淫事2| 视频一区二区黄色线观看| 九九久久精品久久久精品| 在线观看那种视频你懂的| 一区二区三区国产日韩| 国产亚洲视频香蕉一区| 欧美日韩国产亚洲三级理论片| 青青免费操手机在线视频| 国产丝袜极品黑色高跟鞋| 亚洲伦理中文字幕在线观看 | 少妇高潮呻吟浪语91| 亚洲午夜av一区二区| 黄色在线免费高清观看| 欧美区一区二区在线观看 | 欧美人妻盗摄日韩偷拍| 国产精品丝袜美腿一区二区| 91超频在线视频中文字幕 |