數組及其內存管理

程序須要多個類型相同的變量時能夠考慮用數組。java

java 數組是引用類型的變量(具備java引用變量的特徵)數組

1.java數組是靜態的

當數組被初始化後,該數組佔用的內存空間,數組長度都是不可變的。java數組必須初始化才能使用(即建立實際的數組對象,在內存中爲數組對象分配內存空間,併爲每一個數組元素指定初始值)spa

初始化方式(兩種):

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

如:int [] score = new int[]{99,89,79,69,59}; 另外一種寫法: int [] score = {99,89,79,69,59};指針

對於靜態初始化方式,無需指定長度,指定數組元素,由系統來決定數組的長度。對象

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

如:int [] score = new int[5];索引

對於動態初始化方式,只需指定長度(即爲每一個數組元素指定所需的內存空間)系統將負責爲這些元素分配初始值。指定初始值時有如下規則:接口

數組元素是基本類型的整型(byte,short, int,lang),則數組元素的值是0;ip

數組元素是基本類型的浮點型(float,double),則數組元素的值是0.0;內存

數組元素是基本類型的布爾型(boolean),則數組元素的值是false;it

數組元素是基本類型的字符型(char),則數組元素的值是‘\u0000’;

數組元素是基本類型的引用類型(String,類,接口,數組),則數組元素的值是null;

不論採用哪一種方式初始化數組,一旦初始化完成,該數組的長度(score.length)就不可改變。不要同時使用靜態初始化和動態初始化。

java數組是靜態的,一旦數組初始化完成,數組元素的內存空間分配即結束,程序只能該改變數組元素的值,沒法改變數組長度。
javaScript這種動態語言的數組長度是能夠動態改變的。

var arr = [];

document.writeln(「arr的長度是:」+arr.length);

arr[2] = 1;

arr[4] = 4;

document.writeln("arr的長度是:"+arr.length);

第一次輸出爲0,第二次輸出爲5;先定義一個名爲arr的空數組,它的長度是0,而後爲arr數組的第三個,第五個元素賦值時,數組長度變成了5。

Java 數組是一種引用類型的變量,數組變量並非數組自己,它只是指向堆內存中的數組對象,所以能夠改變一個數組變量所引用的堆內存中的數組,這樣就能夠形成數組長度可變的假象。其實變化的是數組變量,而不是該數組變量所指向的內存。若是沒有任何變量引用堆中的數組,它就會變成垃圾,等待垃圾回收機制回收。

數組對象和數組變量:

java的數組變量只是引用類型的變量,並非數組對象的自己,只要讓數組變量指向有效的數組對象,程序中就可使用該數組變量。

如:int [ ] nums = {1,2,3,4,5};

//聲明一個prices 數組。

int [] prices;

//讓prices數組指向nums所引用的數組。

prices = nums;

System.out.print(prices.lentgh);

結果爲5.

數組變量和數組對象:

數組變量相似於C語言中的指針,只是一個引用變量

數組變量,並不須要所謂的初始化,只要讓數組變量指向一個有效的數組對象(堆內存中連續的內存空間),程序便可正常使用該數組變量。

數組對象就是保存在堆內存中的連續內存空間

數組執行初始化,其實並不是對數組變量執行初始化,而是在堆內存中建立數組對象(在堆內存中分配一塊連續的內存空間,內存空間的長度就是數組元素的個數)。

java 程序中的引用變量不須要通過初始化操做,須要進行初始化的是引用變量所引用的對象(堆內存中的空間)。

 

基本類型數組的初始化:

數組元素的值直接存儲在對應的數組元素中,如:int [] score = {99,89,79,69,59};程序直接先爲數組分配內存空間,再將數組元素的值存入對應的內存裏。

程序運行過程當中的「變量」,能夠把它理解爲一種容器,瓶子用於存儲水,而變量用於存儲值,也就是數據。

指定類型的瓶子裝指定的水,指定類型的變量只能存儲指定類型的值。

全部的局部變量都是存放在棧內存中保存的,不論是基本數據類型,仍是引用數據類型的變量,都是存儲在各自的方法棧內存中的,但引用類型的變量所引用的對象(包括數組,對象)則老是在堆內存中的。

java 中,堆內存中的對象是不容許直接訪問的,只能經過引用變量訪問堆內存中的對象。

如:int [] score  = {1,2,3,4,5};本質上是main棧區的引用變量int [] score,可是使用score.length, score[1]時,系統會自動變爲訪問堆內存中的數組對象。

究竟什麼時候引用類的變量只是棧內存中的變量自己,什麼時候又變成了引用實際的java對象。規則以下:引用變量本質上只是一個指針,只要程序經過引用變量訪問屬性,或者經過引用變量來調取方法,該引用變量就會被它的引用的對象替代。

這也是經常會犯的錯誤(NullPointException);當經過引用變量來訪問實例屬性,或者調用非靜態方法時,若是該引用變量還未引用一個有效的對象(堆內存中的空間),程序就會報空指針異常。

 

引用類型數組的初始化:

引用類型數組的數組元素依然是引用類型的,所以數組元素裏存儲的仍是引用(指向堆內存中的一塊內存,這塊內存裏存儲了該引用變量所引用的對象(包括數組和java對象(堆內存的空間))),對於引用類型的數組而言,它的數組元素其實就是一個引用類型的變量,所以能夠指向任何有效(強類型的約束)的內存。

 

使用數組:

當數組引用變量指向一個有效的數組對象以後,程序就能夠經過該數組引用變量來訪問數組對象。java不能夠直接訪問堆內存中的數據,所以沒法直接訪問堆內存中的數組對象,只能經過數組引用變量來訪問數組。

這樣作的目的是爲了保證程序更加健壯,若是程序直接訪問並修改堆內存中數據,可能會破壞內存中的數據完整性,從而致使程序crash。

數組元素就是變量:只要在已有數據類型以後增長[]符號,就會產生一個新的數組類型,

如:

int  int[]   int類型變成了int[]數組類型   

Student  Student[]  Student類型變成了Student[]數組類型

int[]   int[][] int[]類型變成了int[][]數組類型

當程序須要多個類型相同的變量來保存程序狀態時,能夠考慮使用數組來保存這些變量。當一個數組初始化完成以後,就至關於定義了多個類型相同的變量。

不管哪一種類型的數組,其數組元素其實至關於一個普通變量,把數組類型去掉一組[]後獲得的類型就是該數組元素的類型。

如:

int []   數組元素是int 類型的變量

Student[]數組元素是Student類型的變量

int[][] 數組元素是int[]類型的變量。

當經過索引來使用數組元素時,將該數組元素當成普通變量使用便可,包括訪問該數組元素的值,爲數組元素賦值等。

 

沒有多維數組

前面已經指出,只要在已有數據類型以後增長方括號,就會產生一個新的數組類型,若是是int ,增長[] 就是int[] 這個數組類型,若是再以int[]  爲已有類型,增長[] 就獲得int[][] 類型,依然是數組類型,若是再以int[][]類型爲已有類型,增長方括號就獲得int[][][]類型,依然是數組類型。

反過來,將數組類型最後一組[] 去掉就獲得了數組元素的類型。對於int[][][] 類型的數組,數組元素就是int[][],數組元素就是int[]類型的變量,對於int[] 類型的數組,數組元素就至關於int類型的變量。

上面也是多維數組處理的邏輯,所謂的多維數組(n)就是由n-1維數組對象組成的。

相關文章
相關標籤/搜索