假定我們現在想寫一個方法,同時不希望它僅僅返回一樣東西,而是想返回一系列東西。此時,象C和C++這樣的語言會使問題復雜化,因為我們不能返回一個數組,只能返回指向數組的一個指針。這樣就非常麻煩,因為很難控制數組的“存在時間”,它很容易造成內存“漏洞”的出現。
Java采用的是類似的方法,但我們能“返回一個數組”。當然,此時返回的實際仍是指向數組的指針。但在Java裡,我們永遠不必擔心那個數組的是否可用——只要需要,它就會自動存在。而且垃圾收集器會在我們完成後自動將其清除。
作為一個例子,請思考如何返回一個字串數組:
//: IceCream.java
// Returning arrays from methods
public class IceCream {
static String[] flav = {
"Chocolate", "Strawberry",
"Vanilla Fudge Swirl", "Mint Chip",
"Mocha Almond Fudge", "Rum Raisin",
"Praline Cream", "Mud Pie"
};
static String[] flavorSet(int n) {
// Force it to be positive & within bounds:
n = Math.abs(n) % (flav.length + 1);
String[] results = new String[n];
int[] picks = new int[n];
for(int i = 0; i < picks.length; i++)
picks[i] = -1;
for(int i = 0; i < picks.length; i++) {
retry:
while(true) {
int t =
(int)(Math.random() * flav.length);
for(int j = 0; j < i; j++)
if(picks[j] == t) continue retry;
picks[i] = t;
results[i] = flav[t];
break;
}
}
return results;
}
public static void main(String[] args) {
for(int i = 0; i < 20; i++) {
System.out.println(
"flavorSet(" + i + ") = ");
String[] fl = flavorSet(flav.length);
for(int j = 0; j < fl.length; j++)
System.out.println("\t" + fl[j]);
}
}
} ///:~
flavorSet()方法創建了一個名為results的String數組。該數組的大小為n——具體數值取決於我們傳遞給方法的自變量。隨後,它從數組flav裡隨機挑選一些“香料”(Flavor),並將它們置入results裡,並最終返回results。返回數組與返回其他任何對象沒什麼區別——最終返回的都是一個句柄。至於數組到底是在flavorSet()裡創建的,還是在其他什麼地方創建的,這個問題並不重要,因為反正返回的僅是一個句柄。一旦我們的操作完成,垃圾收集器會自動關照數組的清除工作。而且只要我們需要數組,它就會乖乖地聽候調遣。
另一方面,注意當flavorSet()隨機挑選香料的時候,它需要保證以前出現過的一次隨機選擇不會再次出現。為達到這個目的,它使用了一個無限while循環,不斷地作出隨機選擇,直到發現未在picks數組裡出現過的一個元素為止(當然,也可以進行字串比較,檢查隨機選擇是否在results數組裡出現過,但字串比較的效率比較低)。若成功,就添加這個元素,並中斷循環(break),再查找下一個(i值會遞增)。但假若t是一個已在picks裡出現過的數組,就用標簽式的continue往回跳兩級,強制選擇一個新t。用一個調試程序可以很清楚地看到這個過程。
main()能顯示出20個完整的香料集合,所以我們看到flavorSet()每次都用一個隨機順序選擇香料。為體會這一點,最簡單的方法就是將輸出重導向進入一個文件,然後直接觀看這個文件的內容。