1.7 Java到底有没有多维数组?
Java 中沒有多維數(shù)組的概念,從數(shù)組底層的運(yùn)行機(jī)制上來看 Java 沒有多維數(shù)組,但是 Java 提供了支持多維數(shù)組的語法,可以實(shí)現(xiàn)多維數(shù)組的功能。
Java 語言里的數(shù)組類型是引用類型,因此數(shù)組變量其實(shí)是一個(gè)引用,這個(gè)引用指向真實(shí)的數(shù)組內(nèi)存。數(shù)組元素的類型也可以是引用,如果數(shù)組元素的引用再次指向真實(shí)的數(shù)組內(nèi)存,這種情形看上去很像多維數(shù)組。
定義數(shù)組類型的語法type[] arrName;是典型的一維數(shù)組的定義語法,其中 type 是數(shù)組元素的類型。如果希望數(shù)組元素也是一個(gè)引用,而且是指向 int 數(shù)組的引用,則可以把 type 具體成 int[](前面已經(jīng)指出,int[] 就是一種類型,int[] 類型的用法與普通類型并無任何區(qū)別),那么上面定義數(shù)組的語法就是int[][] arrName。
如果把 int 這個(gè)類型擴(kuò)大到 Java 的所有類型(不包括數(shù)組類型),則出現(xiàn)了定義二維數(shù)組的語法:
type[][] arrName;Java 語言采用上面的語法格式來定義二維數(shù)組,但它的實(shí)質(zhì)還是一維數(shù)組,只是其數(shù)組元素也是引用,數(shù)組元素里保存的引用指向一維數(shù)組。
接著對(duì)這個(gè)“二維數(shù)組”執(zhí)行初始化,同樣可以把這個(gè)數(shù)組當(dāng)成一維數(shù)組來初始化,把這個(gè)“二維數(shù)組”當(dāng)成一個(gè)一維數(shù)組,其元素的類型是 type[] 類型,則可以采用如下語法進(jìn)行初始化:
arrName = new type[length][]上面的初始化語法相當(dāng)于初始化了一個(gè)一維數(shù)組,這一維數(shù)組的長(zhǎng)度是 length。同樣,因?yàn)檫@個(gè)一維數(shù)組的數(shù)組元素是引用類型(數(shù)組類型)的,所以系統(tǒng)為每個(gè)數(shù)組元素都分配初始值:null。
這個(gè)二維數(shù)組實(shí)際上完全可以當(dāng)成一維數(shù)組使用:使用new type[length]初始化一維數(shù)組后,相當(dāng)于定義了 length 個(gè) type 類型的變量。類似的,使用new type[length][]初始化這個(gè)數(shù)組后,相當(dāng)于定義了 length 個(gè) type[] 類型的變量。當(dāng)然,這些 type[] 類型的變量都是數(shù)組類型,因此必須再次初始化這些數(shù)組。
下面程序示范了如何把二維數(shù)組當(dāng)成一維數(shù)組處理。
public class TwoDimensionTest {public static void main(String[] args) {// 定義一個(gè)二維數(shù)組int[][] a;// 把a(bǔ)當(dāng)成一維數(shù)組進(jìn)行初始化,初始化a是一個(gè)長(zhǎng)度為4的數(shù)組// a數(shù)組的數(shù)組元素又是引用類型a = new int[4][];// 把a(bǔ)數(shù)組當(dāng)成一維數(shù)組,遍歷a數(shù)組的每個(gè)數(shù)組元素for (int i = 0, len = a.length; i < len; i++) {System.out.println(a[i]); // 輸出 null null null null}// 初始化a數(shù)組的第一個(gè)元素a[0] = new int[2];// 訪問a數(shù)組的第一個(gè)元素所指數(shù)組的第二個(gè)元素a[0][1] = 6;// a數(shù)組的第一個(gè)元素是一個(gè)一維數(shù)組,遍歷這個(gè)一維數(shù)組for (int i = 0, len = a[0].length; i < len; i++) {System.out.println(a[0][i]); // 輸出 0 6}} }上面程序中粗體字代碼部分把 a 這個(gè)二維數(shù)組當(dāng)成一維數(shù)組處理,只是每個(gè)數(shù)組元素都是 null,所以看到輸出結(jié)果都是 null。下面結(jié)合示意圖來說明這個(gè)程序的執(zhí)行過程。
程序中代碼int[][] a;將在棧內(nèi)存中定義一個(gè)引用變量,這個(gè)變量并未指向任何有效的內(nèi)存空間,此時(shí)的堆內(nèi)存中還未為這行代碼分配任何存儲(chǔ)區(qū)。
程序中代碼a = new int[4][];對(duì) a 數(shù)組執(zhí)行初始化,這行代碼讓 a 變量指向一塊長(zhǎng)度為 4 的數(shù)組內(nèi)存,這個(gè)長(zhǎng)度為 4 的數(shù)組里每個(gè)數(shù)組元素都是引用類型(數(shù)組類型),系統(tǒng)為這些數(shù)組元素分配默認(rèn)的初始值:null。此時(shí) a 數(shù)組在內(nèi)存中的存儲(chǔ)示意圖如圖 1 所示。
從圖 1 來看,雖然聲明 a 是一個(gè)二維數(shù)組,但這里絲毫看不出它是一個(gè)二維數(shù)組的樣子,完全是一維數(shù)組的樣子。這個(gè)一維數(shù)組的長(zhǎng)度是 4,只是這 4 個(gè)數(shù)組元素都是引用類型,它們的默認(rèn)值是 null。所以程序中可以把 a 數(shù)組當(dāng)成一維數(shù)組處理,依次遍歷 a 數(shù)組的每個(gè)元素,將看到每個(gè)數(shù)組元素的值都是 null。
由于 a 數(shù)組的元素必須是 int[] 數(shù)組,所以接下來的程序?qū)?a[0] 元素執(zhí)行初始化,也就是讓圖 1 右邊堆內(nèi)存中的第一個(gè)數(shù)組元素指向一個(gè)有效的數(shù)組內(nèi)存,指向一個(gè)長(zhǎng)度為 2 的 int 數(shù)組。因?yàn)槌绦虿捎脛?dòng)態(tài)初始化 a[0] 數(shù)組,因此系統(tǒng)將為 a[0] 所引用數(shù)組的每個(gè)元素分配默認(rèn)的初始值:0,然后程序顯式為 a[0] 數(shù)組的第二個(gè)元素賦值為 6。此時(shí)在內(nèi)存中的存儲(chǔ)示意圖如圖 2 所示。
圖 2 中灰色覆蓋的數(shù)組元素就是程序顯式指定的數(shù)組元素值。TwoDimensionTest.java 接著迭代輸出 a[0] 數(shù)組的每個(gè)數(shù)組元素,將看到輸出 0 和 6。
是否可以讓圖 2 中灰色覆蓋的數(shù)組元素再次指向另一個(gè)數(shù)組?這樣不就可以擴(kuò)展成三維數(shù)組,甚至擴(kuò)展成更多維的數(shù)組嘛?
不能!至少在這個(gè)程序中不能。因?yàn)?Java 是強(qiáng)類型語言,當(dāng)定義 a 數(shù)組時(shí),已經(jīng)確定了 a 數(shù)組的數(shù)組元素是 int[] 類型,則 a[0] 數(shù)組的數(shù)組元素只能是 int 類型,所以灰色覆蓋的數(shù)組元素只能存儲(chǔ) int 類型的變量。對(duì)于其他弱類型語言,例如 JavaScript 和 Ruby 等,確實(shí)可以把一維數(shù)組無限擴(kuò)展,擴(kuò)展成二維數(shù)組、三維數(shù)組…,如果想在 Java 語言中實(shí)現(xiàn)這種可無限擴(kuò)展的數(shù)組,則可以定義一個(gè) Object[] 類型的數(shù)組,這個(gè)數(shù)組的元素是 Object 類型,因此可以再次指向一個(gè) Object[] 類型的數(shù)組,這樣就可以從一維數(shù)組擴(kuò)展到二維數(shù)組、三維數(shù)組…
從上面程序中可以看出,初始化多維數(shù)組時(shí),可以只指定最左邊維的大小;當(dāng)然,也可以一次指定每一維的大小。例如下面代碼:
// 同時(shí)初始化二維數(shù)組的兩個(gè)維數(shù) int[][] b = new int[3][4];上面代碼將定義一個(gè) b 數(shù)組變量,這個(gè)數(shù)組變量指向一個(gè)長(zhǎng)度為 3 的數(shù)組,這個(gè)數(shù)組的每個(gè)數(shù)組元素又是一個(gè)數(shù)組類型,它們各指向?qū)?yīng)的長(zhǎng)度為 4 的 int[] 數(shù)組,每個(gè)數(shù)組元素的值為 0。這行代碼執(zhí)行后在內(nèi)存中的存儲(chǔ)示意圖如圖 3 所示。
還可以使用靜態(tài)初始化方式來初始化二維數(shù)組。使用靜態(tài)初始化方式來初始化二維數(shù)組時(shí),二維數(shù)組的每個(gè)數(shù)組元素都是一維數(shù)組,因此必須指定多個(gè)一維數(shù)組作為二維數(shù)組的初始化值。如下代碼所示:
上面代碼執(zhí)行后內(nèi)存中的存儲(chǔ)示意圖如圖 4 所示。
通過上面講解可以得到一個(gè)結(jié)論:二維數(shù)組是一維數(shù)組,其數(shù)組元素是一維數(shù)組。三維數(shù)組也是一維數(shù)組,其數(shù)組元素是二維數(shù)組…… 從這個(gè)角度來看,Java 語言里沒有多維數(shù)組。
總結(jié)
以上是生活随笔為你收集整理的1.7 Java到底有没有多维数组?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.6 Java数组也是一种数据类型
- 下一篇: 1.8 Arrays工具类