小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 Baruch 2017-09-05

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

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

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

就單純的執(zhí)行這兩條語句,不考慮編譯器的優(yōu)化的話,a=a+b的執(zhí)行效率是低于a+=b的,因?yàn)樗噙M(jìn)行了一步中間變量的操作,而且會(huì)多占用一個(gè)變量的空間。而Java編譯器默認(rèn)對(duì)其進(jìn)行了優(yōu)化,優(yōu)化之后兩條語句都當(dāng)做 a+=b來執(zhí)行了,所以實(shí)際上是沒有任何卻別的。

其次說一下有關(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
 }
}

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

我們將a=a+b注釋掉,javac編譯完之后,再使用反編譯軟件(例如XJad)打開Test.class文件,會(huì)發(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進(jìn)行了強(qiáng)制類型轉(zhuǎn)換,和 a=(int)((float)a+b)是等價(jià)的!

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

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

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

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

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

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

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

如果是final 修飾的變量,進(jìn)行運(yùn)算的時(shí)候則不會(huì)出現(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;
 }
}

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

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

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

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

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

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

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

Java 8簡(jiǎn)明教程 http://www./Linux/2014-03/98754.htm

Java對(duì)象初始化順序的簡(jiǎn)單驗(yàn)證 http://www./Linux/2014-02/96220.htm

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

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

linux

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多