假定我們現在想寫一個方法,同時不希望它僅僅返回一樣東西,而是想返回一系列東西。此時,象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()每次都用一個隨機順序選擇香料。為體會這一點,最簡單的方法就是將輸出重導向進入一個文件,然後直接觀看這個文件的內容。