【Java数组笔记】4-1 数组初步
§4-1 Java 数组初步
在本章内容中,我们将要开始学习 Java 中的数组。
4-1.1 何为数组?
数组(Array)是相同类型数据的有序集合。
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数组元素都可以通过一个下标来访问它们。
使用数组可以将多个相同类型的变量整合至一起,避免多个重复变量,使程序变得简单。
4-1.2 数组的声明与创建
首先让我们来声明一个数组,这里以int
数组为例。语法:
数据类型[] 数组名称; //首选声明方法
数据类型 数组名称[]; //效果相同,但不是首选方法
//这里我们声明一个整型数组:
int[] nums;
声明好数组后,我们需要创建数组。语法:
数组名称 = new 数据类型[数组大小]
//例如,我们创建一个空间大小为 10 的数组,即该数组可存放 10 个元素:
nums = new int[10];
但是,为了方便,我们也会合并数组的声明与创建。如:
数据类型[] 数组名称 = new 数据类型[数组大小]
现在,我们就创建好了一个数组。
4-1.3 访问数组
既然我们已经有了一个数组,那么我们尝试赋值数组中的元素(初始化,initialization)。
注意,数组元素的下标范围为[0, length-1]
:
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;
nums[5] = 6;
nums[6] = 7;
nums[7] = 8;
nums[8] = 9; //第 10 个元素暂且不赋值
接下来我们遍历数组中的元素,并将其输出:
for (int i = 0; i < nums.length; i++) {
System.out.println("nums[" + i + "]: " + nums[i]);
}
我们可以通过arrays.length
来获取数组长度。
我们也可以用for
的增强型用法来遍历数组:
for (int x: nums) {
System.out.println("nums[" + x + "]: " + nums[x])
}
运行,得结果如图所示:
可见,当数组中元素尚未赋值时,其值为该数据类型下的默认值。
4-1.4 注意事项
数组具有以下特点:
- 数组长度都是固定的。数组一旦被创建,其大小就不可被改变,若越界,则会报错(见 4-1.5);
- 数组当中的元素必须是相同类型,不允许出现混合类型;
- 数组中的元素可以是任何数据类型,包括基本数据类型和引用类型;
- 数组变量属于引用类型,数组也可看作是对象,数组中每个元素相当于该对象的成员变量。数组本身就是对象,在 Java 中,对象存在堆(heap)中,因此数组无论保存原始类型还是其他对象类型,数组对象本身就是存在堆中的。
另外,上文所用的数组初始化方法是其中一种,另一种初始化方式为静态初始化。
我们来看个例子:
public class Demo03 {
public static void main(String[] args) {
//初始化方式
//静态初始化
int[] nums = {1,2,3,4,5,6,7,8}; //创建 + 赋值
Demo02[] nums2 = {new Demo02(),new Demo02()}; //引用数据类型,引用自另一个类
//动态初始化:包含默认初始化
int[] b = new int[5]; //此时默认值均为 0
b[0] = 1;
b[1] = 1;
b[2] = 1;
b[3] = 1;
b[4] = 1;
}
}
注意到,当使用动态初始化时,由于已经在堆中开辟空间,此时数组中元素都被默认初始化。
数组的默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一旦分配空间,其中的每个元素也按照实例变量同样的方式被隐式初始化。
4-1.5 内存分析
我们来看看 Java 的内存分析:
由 4-1.4 中可知,Java 数组对象本身存在于堆中,那么我们接下来通过代码来分析在声明、创建和初始化数组时内存发生的变化。
我们来解释下上图所述流程:
- 当我们声明数组时,堆中并未发生变化,反而在栈中存放了所声明的数组变量;
- 随后,当我们创建变量时,在堆中开辟了一块内存空间用以存放数组中元素数据(在本例中,当前所有元素值均默认为
0
; - 最后,当我们初始化值时,我们才会更改数组中每个元素的值。
可见,当数组被创建时,其所开辟的内存空间就已确定,随后不可更改。
那么,我们若要是强行输出该数组中不存在的第 11 个元素呢?我们会得到如下结果:
java.lang.ArrayIndexOutOfBoundsException
:数组下标越界异常。