java 數組和內存


java數組的初始化分爲兩種方式:


靜態初始化:初始化時由程序員顯示指定每個數組元素的初始值,由系統決定數組長度

動態初始化:初始化時程序員只指定數組長度,由系統爲數組元素分配初始值。


不管採用哪兒種方式初始化Java數組,一旦初始化完成,該數組的長度就不可變,可以通過length來獲取數組的長度信息。


如上圖當我們用上面兩種方式定義一個數組時,例如 string[ ]  one = new string[ ] { '1', '2','3'};  靜態方式初始化      string [ ]  two= new string[ 5]; 動態初始化

執行動態初始化的時候,只給定了數組的長度,系統會根據你給的數據類型爲數組賦初值

數組元素是整型,則全爲0

是浮點類型,則爲0.0

是布爾類型,則爲false

是引用類型,比如接口,類和數組, 則爲Null


one 和two是數組變量,它們存儲在左邊的棧去中,而數組對象存儲在堆內存中

注意; 不要同時使用靜態和動態初始化


java數組是靜態的,一旦爲數組初始化完成,數組元素的內存空間分配結束,我們只能改變數組中的元素值,但無法改變其長度。java的數組變量是一種引用類型的變量,數組變量並不是數組本身,它只是指向堆內存中的數組對象。即使你將 one=two; 讓one指向two,one原先指向的那個數組對象還是長度爲3,不會變成5。這樣操作之後,one原先指向的那個數組對象因爲沒有引用變量指向它,它會成爲堆內存中的垃圾,等垃圾回收機制來收回。


我們說的數組一定要初始化,並不是指數組變量,而是數組對象本身要進行初始化,就是說在堆內存中的數組對象要初始化。例如 string[ ]  three;  three=one; 我們沒有對three進行初始化,但是它指向了已經分配好內存的One數組對象,這是可以的。

所有局部變量都是放在棧內存裏保存的,不管是基本類型的變量,還是引用類型的變量,都是存儲在各自的方法棧區中,但引用類型所引用的對象總是存儲在堆內存中。


對於java而言,堆內存中的對象,不管是數組對象,還是普通的Java對象通常不允許直接訪問,爲了訪問堆內存中的對象,通常只能通過引用變量。


我們比較困惑的地方是,引用類型變量何時是一個棧區的變量,何時是引用實際的java對象? 其實,引用變量實際上是一個指針,只要程序通過引用變量訪問屬性,或者通過調用引用變量來調用方法,該引用變量將會由它所引用的對象代替。


引用類型數組的初始化:

public class person {

public int age;

public double height; 

  }

public class refiernecearraytest 

  {

         public static void main/(string [ ] args)

{    

person[ ] students; //  引用類型數組

students = new person[2];

person zhang=new person();

zhang.age=23;

zhang.height=190;

person  lee=24;

lee.age=19;

lee.height=189;

students[0]=zhang;

students[1]=lee;

}

內存分配關係如下,students是一個引用類型數組,數組元素是引用變量,引用變量再指向具體的對象zhang和lee


此時zhang 和students[0]是指向同一個內存區的。lee和students[1]是指向同一個內存區的。



當數組引用變量指向一個有效的數組對象之後,程序就可以通過該數組引用變量來訪問數組對象。java語言不允許直接訪問堆內存中的數據,因此無法直接訪問堆內存中的數組對象,程序通過數組引用變量來訪問數組。需要注意的是main方法聲明的變量都屬於局部變量,因此它們都被保存在main方法棧中,但數組元素則作爲數組對象的一部分,總是保存在堆內存中,不管它是基本類型的數組元素還是引用類型的數組元素。


Java將多維數組看成一維數組來處理。比如聲明 int [ ] [ ]  a;  初始化多維數組時可以先只初始化最左邊的維數。其實length這個函數確切的說不是返回數組的長度,數組length屬性返回系統爲該數組所分配的連續內存空間的長度,比如int[3][ ] ;其實返回length是4 






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章