Vector的用法很簡單,這已在前面的例子中得到了證明。盡管我們大多數時候只需用addElement()插入對象,用elementAt()一次提取一個對象,並用elements()獲得對序列的一個“枚舉”。但仍有其他一系列方法是非常有用的。同我們對於Java庫慣常的做法一樣,在這裡並不使用或講述所有這些方法。但請務必閱讀相應的電子文檔,對它們的工作有一個大概的認識。
1. 崩潰Java
Java標准集合裡包含了toString()方法,所以它們能生成自己的String表達方式,包括它們容納的對象。例如在Vector中,toString()會在Vector的各個元素中步進和遍歷,並為每個元素調用toString()。假定我們現在想打印出自己類的地址。看起來似乎簡單地引用this即可(特別是C++程序員有這樣做的傾向):
//: CrashJava.java // One way to crash Java import java.util.*; public class CrashJava { public String toString() { return "CrashJava address: " + this + "\n"; } public static void main(String[] args) { Vector v = new Vector(); for(int i = 0; i < 10; i++) v.addElement(new CrashJava()); System.out.println(v); } } ///:~
若只是簡單地創建一個CrashJava對象,並將其打印出來,就會得到無窮無盡的一系列違例錯誤。然而,假如將CrashJava對象置入一個Vector,並象這裡演示的那樣打印Vector,就不會出現什麼錯誤提示,甚至連一個違例都不會出現。此時Java只是簡單地崩潰(但至少它沒有崩潰我的操作系統)。這已在Java 1.1中測試通過。
此時發生的是字串的自動類型轉換。當我們使用下述語句時:
"CrashJava address: " + this
編譯器就在一個字串後面發現了一個“+”以及好象並非字串的其他東西,所以它會試圖將this轉換成一個字串。轉換時調用的是toString(),後者會產生一個遞歸調用。若在一個Vector內出現這種事情,看起來堆棧就會溢出,同時違例控制機制根本沒有機會作出響應。
若確實想在這種情況下打印出對象的地址,解決方案就是調用Object的toString方法。此時就不必加入this,只需使用super.toString()。當然,采取這種做法也有一個前提:我們必須從Object直接繼承,或者沒有一個父類覆蓋了toString方法。