假設(shè)這個錯誤終于被改正了,但同時,類 Example 的一個子類也被創(chuàng)建了,如清單 2 所示:
清單 2. 試圖捕捉象清單 1 這樣的不正確的調(diào)用
import java.util.*;
class Example {
public int product(Iterator i) { return productHelp(i, 1); }
int productHelp(Iterator i, int accumulator) { if (i.hasNext()) { return productHelp(i, accumulator * ((Integer)i.next()).intValue()); } else { return accumulator; } } }
// And, in a separate file:
import java.util.*;
public class Example2 extends Example { int productHelp(Iterator i, int accumulator) { if (accumulator < 1) { throw new RuntimeException("accumulator to productHelp must be >= 1"); } else { return super.productHelp(i, accumulator); } }
public static void main(String[] args) { LinkedList l = new LinkedList(); l.add(new Integer(0)); new Example2().product(l.listIterator()); } }
然而,您可以看到類 Example 的 productHelp 是嚴(yán)格尾遞歸的。假設(shè)一個靜態(tài)編譯器想把這個方法的正文轉(zhuǎn)換成一個循環(huán),如清單 3 所示:
清單 3. 靜態(tài)編譯不會優(yōu)化尾調(diào)用的一個示例 int productHelp(Iterator i, int accumulator) { while (i.hasNext()) { accumulator *= ((Integer)i.next()).intValue(); } return accumulator; }
試試 IBM developer kit for Java version 1.3。我想您會對它的性能感到滿足的。
欲具體了解尾遞歸及其到迭代的轉(zhuǎn)換,請參閱 CMU Common Lisp User′s Manual(CMU Common Lisp 用戶手冊)。雖然這本手冊是(當(dāng)然是)為 Common Lisp 寫的,但其中關(guān)于尾遞歸的討論也適用于其他語言,包括 Java 語言。
對提高您 Java 代碼的性能有愛好?在二月底于紐約召開的國際 Java 開發(fā)大會上,性能專家 Peter Haggar 在他的音頻演示中討論了這個問題的本質(zhì)。
閱讀 Eric 關(guān)于診斷 Java 代碼的完整系列。
關(guān)于作者 Eric Allen 在 Cornell 大學(xué)獲得了計算機科學(xué)及數(shù)學(xué)的學(xué)士學(xué)位。他目前是 Cycorp,Inc 的主要 Java 軟件開發(fā)人員帶頭人,編程部的副經(jīng)理,還是位于 JavaWorld 的 Java 初學(xué)者論壇的主持人。他還是 Rice 大學(xué)編程語言小組的兼職研究生。他的研究涉及在源程序和字節(jié)碼層次上的正規(guī)語義模型和 Java 語言擴展的開發(fā)。目前,他正在為 NextGen 編程語言實現(xiàn)一種從源代碼到字節(jié)碼的編譯器,這也是 Java 語言的泛型運行時類型的一種擴展。可通過 eallen@cyc.com 與 Eric 聯(lián)系。