Java 中没有多维数组的概念,从数组底层的运行机制上来看 Java 没有多维数组,但是 Java 提供了支持多维数组的语法,可以实现多维数组的功能。

Java 语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存。数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。

定义数组类型的语法type[] arrName;是典型的一维数组的定义语法,其中 type 是数组元素的类型。如果希望数组元素也是一个引用,而且是指向 int 数组的引用,则可以把 type 具体成 int[](前面已经指出,int[] 就是一种类型,int[] 类型的用法与普通类型并无任何区别),那么上面定义数组的语法就是int[][] arrName。

如果把 int 这个类型扩大到 Java 的所有类型(不包括数组类型),则出现了定义二维数组的语法:

type[][] arrName;

Java 语言采用上面的语法格式来定义二维数组,但它的实质还是一维数组,只是其数组元素也是引用,数组元素里保存的引用指向一维数组。

接着对这个“二维数组”执行初始化,同样可以把这个数组当成一维数组来初始化,把这个“二维数组”当成一个一维数组,其元素的类型是 type[] 类型,则可以采用如下语法进行初始化:

arrName = new type[length][]

上面的初始化语法相当于初始化了一个一维数组,这一维数组的长度是 length。同样,因为这个一维数组的数组元素是引用类型(数组类型)的,所以系统为每个数组元素都分配初始值:null。

这个二维数组实际上完全可以当成一维数组使用:使用new type[length]初始化一维数组后,相当于定义了 length 个 type 类型的变量。类似的,使用new type[length][]初始化这个数组后,相当于定义了 length 个 type[] 类型的变量。当然,这些 type[] 类型的变量都是数组类型,因此必须再次初始化这些数组。

下面程序示范了如何把二维数组当成一维数组处理。

public class TwoDimensionTest {public static void main(String[] args) {// 定义一个二维数组int[][] a;// 把a当成一维数组进行初始化,初始化a是一个长度为4的数组// a数组的数组元素又是引用类型a = new int[4][];// 把a数组当成一维数组,遍历a数组的每个数组元素for (int i = 0, len = a.length; i < len; i++) {System.out.println(a[i]); // 输出 null null null null}// 初始化a数组的第一个元素a[0] = new int[2];// 访问a数组的第一个元素所指数组的第二个元素a[0][1] = 6;// a数组的第一个元素是一个一维数组,遍历这个一维数组for (int i = 0, len = a[0].length; i < len; i++) {System.out.println(a[0][i]); // 输出 0 6}}
}

上面程序中粗体字代码部分把 a 这个二维数组当成一维数组处理,只是每个数组元素都是 null,所以看到输出结果都是 null。下面结合示意图来说明这个程序的执行过程。

程序中代码int[][] a;将在栈内存中定义一个引用变量,这个变量并未指向任何有效的内存空间,此时的堆内存中还未为这行代码分配任何存储区。

程序中代码a = new int[4][];对 a 数组执行初始化,这行代码让 a 变量指向一块长度为 4 的数组内存,这个长度为 4 的数组里每个数组元素都是引用类型(数组类型),系统为这些数组元素分配默认的初始值:null。此时 a 数组在内存中的存储示意图如图 1 所示。

从图 1 来看,虽然声明 a 是一个二维数组,但这里丝毫看不出它是一个二维数组的样子,完全是一维数组的样子。这个一维数组的长度是 4,只是这 4 个数组元素都是引用类型,它们的默认值是 null。所以程序中可以把 a 数组当成一维数组处理,依次遍历 a 数组的每个元素,将看到每个数组元素的值都是 null。

由于 a 数组的元素必须是 int[] 数组,所以接下来的程序对 a[0] 元素执行初始化,也就是让图 1 右边堆内存中的第一个数组元素指向一个有效的数组内存,指向一个长度为 2 的 int 数组。因为程序采用动态初始化 a[0] 数组,因此系统将为 a[0] 所引用数组的每个元素分配默认的初始值:0,然后程序显式为 a[0] 数组的第二个元素赋值为 6。此时在内存中的存储示意图如图 2 所示。

图 2 中灰色覆盖的数组元素就是程序显式指定的数组元素值。TwoDimensionTest.java 接着迭代输出 a[0] 数组的每个数组元素,将看到输出 0 和 6。

是否可以让图 2 中灰色覆盖的数组元素再次指向另一个数组?这样不就可以扩展成三维数组,甚至扩展成更多维的数组嘛?

不能!至少在这个程序中不能。因为 Java 是强类型语言,当定义 a 数组时,已经确定了 a 数组的数组元素是 int[] 类型,则 a[0] 数组的数组元素只能是 int 类型,所以灰色覆盖的数组元素只能存储 int 类型的变量。对于其他弱类型语言,例如 JavaScript 和 Ruby 等,确实可以把一维数组无限扩展,扩展成二维数组、三维数组…,如果想在 Java 语言中实现这种可无限扩展的数组,则可以定义一个 Object[] 类型的数组,这个数组的元素是 Object 类型,因此可以再次指向一个 Object[] 类型的数组,这样就可以从一维数组扩展到二维数组、三维数组…

从上面程序中可以看出,初始化多维数组时,可以只指定最左边维的大小;当然,也可以一次指定每一维的大小。例如下面代码:

// 同时初始化二维数组的两个维数
int[][] b = new int[3][4];

上面代码将定义一个 b 数组变量,这个数组变量指向一个长度为 3 的数组,这个数组的每个数组元素又是一个数组类型,它们各指向对应的长度为 4 的 int[] 数组,每个数组元素的值为 0。这行代码执行后在内存中的存储示意图如图 3 所示。

还可以使用静态初始化方式来初始化二维数组。使用静态初始化方式来初始化二维数组时,二维数组的每个数组元素都是一维数组,因此必须指定多个一维数组作为二维数组的初始化值。如下代码所示:

// 使用静态初始化语法来初始化一个二维数组
String[][] str1 = new String[][]{new String[3], new String[]{"hello"}};
// 使用简化的静态初始化语法来初始化二维数组
String[][] str2 = {new String[3], new String [] {"hello"}};

上面代码执行后内存中的存储示意图如图 4 所示。

通过上面讲解可以得到一个结论:二维数组是一维数组,其数组元素是一维数组。三维数组也是一维数组,其数组元素是二维数组…… 从这个角度来看,Java 语言里没有多维数组。

1.7 Java到底有没有多维数组?相关推荐

  1. int数组初始化_Java中到底有没有多维数组

    Java 中没有多维数组的概念,从数组底层的运行机制上来看 Java 没有多维数组,但是 Java 提供了支持多维数组的语法,可以实现多维数组的功能. Java 语言里的数组类型是引用类型,因此数组变 ...

  2. 韩顺平循序渐进学java 第19讲 多维数组

    19.1 二维数组 高维数组在工作中用到的不多,所以只介绍二维数组. 1.定义 语法:类型 数组名[][]=new 类型[大小][大小] 比如:int a[][]=new int[2][3] 2.分析 ...

  3. Java学习---面向对象与多维数组

    多维数组 定义: n维数组就是元素为n-1维数组的数组 int[] 数组名 int[][] 数组名 int 数组名 [] int[] 数组名[] 初始化: 1 . 数据类型[][] 数组名 = new ...

  4. 小白自学笔记——JAVA基础 3.2 多维数组

    名词解释 Java 语言里提供了支持多维数组的语法. 如果说可以把一维数组当成几何中的线性图形,那么二维数组就相当于是一个表格,像Excel中的表格一样. 对于二维数组的理解,我们可以看成是一维数组a ...

  5. java练习day06-Debug-进制-二维数组-杨辉三角

    Day06 Debug Debug概述: ​ Debug是供程序员使用的程序调试工具,它可以用于查看程序的执行流程,也可以用于追踪程序执行过程来调试程序. Debug操作流程 ​ Debug调试,又被 ...

  6. java中控制台输入二维数组(Scanner类总结)

    由于牛客和LeetCode上的题目不用自己写输入,但实际笔试中都需要从输入开始写,遇到需要从控制台输入二维数组的情况,故对java中的Scanner类作整理和总结. 通过 Scanner 类能获取用户 ...

  7. java中用length求二维数组的长度

    今天刷题的时候碰到二维数组长度的问题,直接敲代码验证~ 用事实说话: 说明length求得的是二维数组的行数,即data[i][j]中的i 但如果要求二维数组的列数呢?很简单,用data[0].len ...

  8. Java基础动态初始化二维数组

    直接上代码: //动态初始化二维数组 public class ArrayTest09 {public static void main(String[] args) {//定义一个二维数组并动态初始 ...

  9. java实现n阶二维数组(n×n)的顺时针旋转90°、180°、270°

    一.首先第一步是要初始化一个你任意的n阶方阵,初始化的语句参考如下: int arr[][] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; 二 ...

最新文章

  1. python更新pip失败-解决Python pip 自动更新升级失败的问题
  2. Bit-Z携手Bit-MY落户马来西亚 已获得经营牌照
  3. Bootstrap3免费单页面模板-Shuffle
  4. oracle 删除表中重复记录,并保留一条
  5. MSSQL · 最佳实践 · 利用文件组实现冷热数据隔离备份方案
  6. python123第6周答案_python123 测验6: 组合数据类型 (第6周)
  7. 滴滴升级“极速拼车”:未拼成可享折扣 拼成更便宜
  8. SAP License:最近的FICO面试题目
  9. SQL Server中自定义函数:用指定的分隔符号分割字符串
  10. 计算机无法识别建行网银盾,建行网银盾无法识别怎么办 几招办法教你轻松解决...
  11. 教程 | 如何用思维导图做自我介绍
  12. html之响应式(自适应)网页设计
  13. 哈罗数据分析(SQL)笔试
  14. 使用C语言教你轻松学会Cantor表
  15. Linux下execl函数与execlp函数的具体详细用法
  16. MySql的下载和安装
  17. ORAN专题系列-16:5G O-RAN FrontHaul前传接口的网络配置管理协议netconf
  18. 【Macbook 软件分享|使用技巧】干货
  19. 2.3 PPT :用logo设计封面
  20. kernel32 ntdll

热门文章

  1. Keras之CNN:基于Keras利用cv2建立训练存储卷积神经网络模型(2+1)并调用摄像头进行实时人脸识别
  2. JAVA_OA(bug篇)(一):SpringMVC的bug1
  3. 五分钟搞定 Linux 文档全部知识,就看这篇文章
  4. spring学习(6)
  5. 前端开发浏览器兼容问题
  6. JNDI 和JDBC的区别
  7. jx problem
  8. myeclipse同时部署两个项目-permgen space
  9. 【C/C++ string】之strcpy函数
  10. 定点c程序之一:定标