foreach迴圈和記憶體中的陣列

LingLee_荊棘鳥發表於2017-08-07

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. 一維陣列
[java] view plain copy
  1. int arr[] = new int[3];  
int[] arr 指向 包含3個整數的陣列. 假設建立的是包含10個整數的陣列,也是同樣的用法 —— 分配指定大小的記憶體,並返回陣列的引用。

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

圖2
同樣的原理,多維陣列也是如此.
3. 陣列分配在記憶體的哪個區域?
Java中的陣列,也是物件(繼承Object),因此陣列所在的區域和物件是一樣的.
我們知道,     

JVM 執行時資料區

  包括 JVM棧,堆記憶體,以及其他區域. 看下面的關於物件的簡單示例,我們一起來了解陣列如何分配,以及引用儲存在哪裡.
[java] view plain copy
  1. class A {  
  2.     int x;  
  3.     int y;  
  4. }  
  5. ...  
  6. public void m1() {  
  7.     int i = 0;  
  8.     m2();  
  9. }  
  10. public void 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

相關文章