熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

深入理解Java延遲綁定

2013-11-23 19:01:54  來源: Java核心技術 

  
  下面幾個類用於確定今天晚餐要喝的酒以及酒的溫度
  
  class Sommelier {
   Wine recommend(String meal) { }
  }
  
  abstract class Wine {
   // 推薦酒的溫度
   abstract float temperature();
  }
  
  class RedWine extends Wine {
   // 紅酒的溫度通常略高於白酒
   float temperature() { return ; }
  }
  
  class WhiteWine extends Wine {
   float temperature() { return ; }
  }
  
  class Bordeaux extends RedWine {
   float temperature() { return ; }
  }
  
  class Riesling extends WhiteWine {
   // 繼承WhiteWine類的溫度
  }
  
  下面的例子利用上面的類推薦一種酒
  
  void example() {
   Wine wine = sommelierrecommend(duck);
   float temp = winetemperature();
  }
  
  example的第二個調用中對於wine對象我們唯一可以肯定的是它是一個Wine但可以是Bordeaux也可以是Riesling或其他另外我們可以肯定wine對象不可能是Wine類本身的實例因為Wine類是一個抽象類編譯源代碼源代碼中的winetemperature()調用將變成invokevirtual Wine/temperature ()F(class文件實際包含的是該文本表示形式的二進制代碼這種文本化的指令描述方法稱為Oolong方法)它表示的是一個方法調用——一個普通的(虛擬)方法調用而不是一個靜態調用它調用的方法是Wine對象的temperature右邊的()F參數稱為簽名(signature)()F這個簽名中的空括號表示方法不需要輸入參數F表示返回值是一個浮點數
  
  JVM執行到該語句時它調用的不一定是Wine定義的temperature方法實際上在本例中JVM不可能調用Wine定義的temperature方法因為該temperature方法是一個虛擬方法JVM首先檢查該對象所屬的類尋找一個符合invokevirtual語句指定的名稱簽名特征的方法如果找不到則檢查該類的超類然後是超類的超類直至找到一個合適的方法實現為止
  
  在本例中如果實際創建的對象是一個Bordeaux則JVM調用Bordeaux類定義的temperature()F該temperature()F方法將返回如果對象是一個RieslingJVM在Riesling類中找不到適當的方法所以繼續查找WhiteWine類在WhiteWine類中找到了一個合適的temperature()F方法該方法的返回值是
  
  因此查找可用方法的過程就是沿著類的繼承樹通過字符串匹配尋找合適方法的過程了解這一原理有助於理解哪些修改不至於影響二進制兼容性
  
  首先重新排列類裡面的方法顯然不會影響到二進制兼容性——這在C++程序中一般是不允許的因為C++程序利用數值性偏移量而不是名稱來確定要調用的方法延遲綁定的關鍵優勢正是在此如果Java也使用方法在類裡面的偏移量來確定要調用的方法必然極大地限制二進制兼容機制的發揮即使極小的改動也可能導致大量的代碼需要重新編譯
  
  ·說明也許有人會認為C++的處理方式要比Java的快理由是根據數值性偏移量尋找方法肯定要比字符串匹配快這種說法有一定道理但只說明了類剛剛裝入時的情況此後Java的JIT編譯器處理的也是數值性偏移量而不再靠字符串匹配的辦法尋找方法因為類裝入內存之後不可能再改變所以這時的JIT編譯器根本無須顧慮到二進制兼容問題因此至少在方法調用這一點上Java沒有理由一定比C++慢
  
  其次還有很重要的一點是不僅僅編譯時需要檢查類的繼承關系而且運行時JVM還要檢查類的繼承關系

From:http://tw.wingwit.com/Article/program/Java/hx/201311/26162.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.