BiBi - JVM -11- 編譯期優(yōu)化

From:深入理解Java虛擬機(jī)

編譯期的三種情況

1)前端編譯器:把java文件轉(zhuǎn)變?yōu)閏lass文件。
2)JIT編譯器:運行期編譯器把字節(jié)碼轉(zhuǎn)變?yōu)闄C(jī)器碼弃榨。
3)AOT編譯器:把java文件編譯成本地機(jī)器碼掉瞳。

對性能的優(yōu)化主要集中在JIT,這樣可以讓那些不是由javac產(chǎn)生的class文件【如:Groovy淫茵、JRuby】也同樣能享受到編譯器優(yōu)化帶來的好處。

javac編譯的過程

(解析與填充符號表 >< 注解處理) > 分析與字節(jié)碼生成

public void foo(final int arg) {
  final int var = 0;
}

public void foo(int arg) {
  int var = 0;
}

上面兩段代碼編譯出來的Class文件是一樣的。由于局部變量在常量池中沒有CONSTANT_Fieldref_info的符號引用碉克,自然就沒有訪問標(biāo)志的信息,所以在Class文件中不可能知道一個局部變量是不是聲明為final赁还。

將局部變量聲明為final妖泄,對運行期是沒有影響的,變量的不變性僅僅由編譯器在編譯期間保障艘策。

語法糖

泛型蹈胡、變長參數(shù)、自動裝箱/拆箱朋蔫、高級for循環(huán)罚渐、內(nèi)部類、枚舉類驯妄、switch支持字符串等荷并,虛擬機(jī)運行時不支持這些語法,它們在編譯階段還原回基礎(chǔ)的語法結(jié)構(gòu)青扔。

如果用戶代碼中沒有提供任何構(gòu)造函數(shù)源织,那編譯器將會添加一個沒有參數(shù)的、訪問性與當(dāng)前類一致的默認(rèn)構(gòu)造函數(shù)微猖,這個工作在【填充符號表】階段完成雀鹃。

把字符串的加操作替換為StringBuffer或StringBuilder的append操作。

void say() {
      String str = "bb" + "cc" + "dd" + "ee";
      str = "aa" + str;
      System.out.println(str);
    }

對應(yīng)的Class為:

void say() {
  String var1 = "bbccddee";
  var1 = "aa" + var1;
  System.out.println(var1);
}

void say() {
  String[] arr = { "aa", "bb", "cc" };
  String res = null;
  for (String str : arr) {
    res += str;
  }
  System.out.println(res);
}

對用的Class為:

void say() {
  String[] var1 = new String[]{"aa", "bb", "cc"};
  String var2 = null;
  String[] var3 = var1;
  int var4 = var1.length;
  for(int var5 = 0; var5 < var4; ++var5) {
    String var6 = var3[var5];
    var2 = var2 + var6;
  }
  System.out.println(var2);
}

void say() {
  List<String> list = new ArrayList<>();
  list.add("ljg");
  for (String s : list) {
    System.out.println(s);
  }
}

對用的Class為:

void say() {
  ArrayList var1 = new ArrayList();
  var1.add("ljg");
  Iterator var2 = var1.iterator();
  while(var2.hasNext()) {
    String var3 = (String)var2.next();
    System.out.println(var3);
  }
}

總結(jié):
1)字符串相加優(yōu)化的場景是有限的励两,所以在開發(fā)中還是要自己主動使用StringBuilder黎茎。
2)高級for循環(huán)會被轉(zhuǎn)化為基本for循環(huán)樣式。
3)泛型會被擦除当悔,轉(zhuǎn)換為手動的類型轉(zhuǎn)換

真泛型:C#傅瞻,在運行期是真實存在的,有自己的虛方法表和類型數(shù)據(jù)盲憎。
偽泛型:Java嗅骄,在編譯后的字節(jié)碼中會擦除泛型信息,替換為原生類型饼疙,并在相應(yīng)的地方插入強制類型轉(zhuǎn)換溺森。對Java而言,ArrayList<int>和ArrayList<String>是同一個類窑眯。

public void method(List<String> list) {
  System.out.println(list.toString());
}

public void method(List<Integer> list) {
  System.out.println(list.toString());
}

上面的代碼不能被編譯屏积,因為擦除后兩個方法簽名一樣。

  • Integer
public static void main(String[] args) {
  Integer a = 1;
  Integer b = 2;
  Integer c = 3;
  Integer d = 3;
  Integer e = 321;
  Integer f = 321;
  Long g = 3L;
  System.out.println(c == d);//ture
  System.out.println(e == f);//falde
  System.out.println(c == (a + b));//true
  System.out.println(c.equals(a + b));//true
  System.out.println(g == (a + b));//true
  System.out.println(g.equals(a + b));//false 因為equals()方法不處理數(shù)據(jù)類型轉(zhuǎn)換
}
  • switch字符串的語法糖
public static void main(String[] args) {
  String str = "a";
  switch (str) {
    case "a":
      System.out.println("aaa");
      break;
    case "b":
      System.out.println("bbb");
      break;
    default:
      break;
  }
}

對應(yīng)的Class為:

public static void main(String[] var0) {
   String var1 = "a";
   byte var3 = -1;
   switch(var1.hashCode()) {
   case 97:
     if (var1.equals("a")) {
       var3 = 0;
     }
     break;
   case 98:
     if (var1.equals("b")) {
       var3 = 1;
     }
   }
   switch(var3) {
   case 0:
     System.out.println("aaa");
     break;
   case 1:
     System.out.println("bbb");
   }
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磅甩,一起剝皮案震驚了整個濱河市炊林,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卷要,老刑警劉巖渣聚,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件独榴,死亡現(xiàn)場離奇詭異,居然都是意外死亡奕枝,警方通過查閱死者的電腦和手機(jī)棺榔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隘道,“玉大人症歇,你說我怎么就攤上這事”∩” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵题画,是天一觀的道長默辨。 經(jīng)常有香客問我,道長苍息,這世上最難降的妖魔是什么缩幸? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮竞思,結(jié)果婚禮上表谊,老公的妹妹穿的比我還像新娘。我一直安慰自己盖喷,他們只是感情好爆办,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著课梳,像睡著了一般距辆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上暮刃,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天跨算,我揣著相機(jī)與錄音,去河邊找鬼椭懊。 笑死诸蚕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的氧猬。 我是一名探鬼主播背犯,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盅抚!你這毒婦竟也來了媳板?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤泉哈,失蹤者是張志新(化名)和其女友劉穎蛉幸,沒想到半個月后破讨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡奕纫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年提陶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匹层。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡隙笆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出升筏,到底是詐尸還是另有隱情撑柔,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布您访,位于F島的核電站铅忿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏灵汪。R本人自食惡果不足惜檀训,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望享言。 院中可真熱鬧峻凫,春花似錦、人聲如沸览露。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽差牛。三九已至铭腕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間多糠,已是汗流浹背累舷。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留夹孔,地道東北人被盈。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像搭伤,于是被迫代替她去往敵國和親只怎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348