1. 程式人生 > >foreach迴圈和記憶體中的陣列

foreach迴圈和記憶體中的陣列

1.首先說一下foreach迴圈

當使用foreach來迭代訪問陣列元素時,迴圈變數book相當於一個臨時變數,系統會把陣列元素依次賦給這個變數,當時對該變數的修改,並不能改變原陣列元素的值。此處還記得Iterator來遍歷嗎,也是不能修改

eg:    for(Book book: books){

book="哈哈哈";

System.out.println(book);//輸出“哈哈哈”

}

System.out.println(books[0]);//還是原來的值

記憶體中的陣列:引用變數存在於棧中,實際值存在堆中,《瘋狂講義》p91

Java中的陣列儲存兩類事物: 原始值(int,char,...),或者引用(物件指標).

當一個物件通過 new 建立,那麼將在堆記憶體中分配一段空間,並且返回其引用(指標).
對於陣列,也是同樣的方式.
1. 一維陣列
  1. int arr[] = newint[3];  
int[] arr 指向 包含3個整數的陣列. 假設建立的是包含10個整數的陣列,也是同樣的用法 —— 分配指定大小的記憶體,並返回陣列的引用。

圖1 2. 二維陣列
二維陣列又有什麼區別呢?實際上,在Java中只有一維陣列。二維陣列本質上也是一維陣列,只是陣列中的每一個元素都指向了另一個一維陣列而已。
  1. int[ ][ ] arr = newint[3][ ];  
  2. arr[0] = newint[3];  
  3. arr[1
    ] = newint[5];  
  4. arr[2] = newint[4];  

圖2 同樣的原理,多維陣列也是如此.
3. 陣列分配在記憶體的哪個區域?
Java中的陣列,也是物件(繼承Object),因此陣列所在的區域和物件是一樣的.
我們知道,    包括 JVM棧,堆記憶體,以及其他區域. 看下面的關於物件的簡單示例,我們一起來了解陣列如何分配,以及引用儲存在哪裡.
  1. class A {  
  2.     int x;  
  3.     int y;  
  4. }  
  5. ...  
  6. publicvoid m1() {  
  7.     int i = 0;  
  8.     m2();  
  9. }  
  10. publicvoid m2() {  
  11.     A a = new A();  
  12. }  
  13. ...  

上面的程式碼片段中,讓我們執行 m1()方法看看發生了什麼:
  1.  當 m1 被呼叫時,一個新的棧幀(Frame-1)被壓入JVM棧中,當然,相關的區域性變數也在 Frame-1中建立,比如 i;
  2.  然後 m1呼叫m2,,又有一個新的棧幀(Frame-2)被壓入到JVM棧中;   m2方法在堆記憶體中建立了A類的一個物件,此物件的引用儲存在 Frame-2的區域性變數 a 中. 此時,堆記憶體和棧記憶體看起來如下所示:


圖3