數組的定義
Java語言支持兩種語法格式定義數組:
- type[] arrayName;
- type arrayName[];
爲了更好的語音及可讀性,應該使用第一種定義語法。 |
數組初始化
數組的初始化方式有兩種:
- 靜態初始化:初始化時由程序員顯式指定每個數組元素的初始值,由系統決定數組長度。
- 動態初始化:初始化時程序員只指定數組長度,由系統爲數組元素分配初始值。
靜態初始化語法如下:
arrayName = new type[]{element1, element2, …}
示例:String[] strs = new String[]{};
此外,還有一種簡化語法,使用數組常量,如下:
arrayName = {element1, element2, …}
示例:int[] ints = {1, 2, 3,};
數組初始化列表的最後一個逗號都是可選的,這一特性使維護長列表變得更容易。 |
動態初始化語法如下:
arrayName = new type[length];
示例:double[] ds = new double[0];
動態初始化涉及數組中每個元素的自動初始化問題。當系統爲每個元素分配內存空間時,其實是通過將內存空間所有二進制位設爲0,以達到分配初始值的目的的。 |
多維數組
二維數組允許如下的初始化語法:
arrName = new type[length][] |
這相當於定義了length個type[]類型的變量,並且此時這些變量都是null。
更一般的,對於更高維的數組,允許僅指定至少最高維的前任意維的維度,如下:
arrName = new type[length1]…[]… |
這導致低維數組元素都是null,所以後續需要對低維數組進行進一步初始化。對低維數組的初始化其實就是數組元素賦值而非定義賦值,所以對於數組常量的賦值方式將不適用。即以下賦值語句將導致編譯錯誤:
intss[1] = {1, 2}; |
當我們說數組時,一般隱含“一維”這個“默認”前綴,並形象地把其看作一個線性列表;二維數組,我們又賦予矩陣一般的形象,這是“面性”的;三維數組被認爲是“體性”的……再高維度的數組似乎就很難形象化了,這使得感觀上很難認知。
實質上,Java裏的數組可以說只有一維的。
我們先從最簡單的多維數組——二維數組來看。一般地,二維數組type[][],該類型的數組變量是一個引用,這個引用指向真實的數組內存對象。此時數組元素類型爲type[],也是引用,這個引用指向一維數組內存對象,其元素爲type類型。
從這裏我們隱隱可以看到遞歸結構的影子,通過觀察更高維數組,這種遞歸結構很容易歸納出來。對於任意高維數組而言,其本質是一個元素類型爲比其低一維的數組組成的一維數組。例如:type[][][][]數組,是一個元素類型爲type[][][]的一維數組,type[][][]數組又是一個元素類型爲type[][]的一維數組……這樣,我們發現,所有數組都是一維的,數組的類型去掉一個[]就是元素類型。
參差數組
由於定義多維數組時,不必定義低維數組的長度,所以這使得多維數組擁有成爲“參差數組”的能力,即同一維度下的數組元素中的數組的長度可以是不同的。如下:
int[][] intss = new int[2][]; intss[0] = new int[]{1, 2}; intss[1] = new int[3]; |
intss是一個二維數組,它有2個元素,都是一維數組,而這2個一維數組,一個長度爲2,另一個長度爲3。這對於多維數組是允許的。
數組的類型
有的書上說,數組不是一個類,因爲無法說出數組的類名。這種說法的準確性是值得商榷的。
首先,每個數組都是有類型的,這一點我們可以透過任意數組都有getClass()方法這點得知。
其次,並非我們不能說出數組的類名,只是盛裝不同類型元素的數組其類型是不同的。
所以,數組的確不是一個類,因爲它是許多類的一個統稱,只是這些類都有相同的集合形式。
下面例舉一些數組的類型:
數組 |
類型(類名) |
byte[] |
[B |
short[] |
[S |
int[] |
[I |
long[] |
[J |
float[] |
[F |
double[] |
[D |
char[] |
[C |
boolean[] |
[Z |
String[] |
[Ljava.lang.String; |
int[][] |
[[I |
可以看出,無論什麼類型的數組,其類名都是以“[”爲前導符的,並且是多少維的數組就會有多少個前導符。另外,對於基本類型的數組而言,其類名都是前導符加上一個特徵大寫字母組成;而對於常規類型的數組而言,其類名是其元素類型完全限定名加上“L”字母前綴並再加前導符組成。