关于数据内存管理一个重要知识点
关于数组变量和数组对象两个概念。 数组变量只是一个引用变量(有点类似于C语言中的指针),而数组对象是保存堆内存空间的连续内存空间。 对于数组执行初始化,其实不是堆数组变量进行初始化,而是在堆内存中创建数组对象 - 就是为该数组对象分配一块连续的内存空间,这块连续的内存 空间就是数组的长度。比如有个数组
1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
String[] a1 = new String[]{"篮球", "足球", "排球", "羽毛球"};
//定义一个 String[] 类型的数组变量
String[] a2 = null;
System.out.println(a2);
//将 a1 数组的引用赋值给 a2
a2 = a1;
System.out.println(a2.length);
}

那如何区分引用变量和数组对象?
当引用变量不调用属性或方法,就是一个引用变量,当调用属性或方法时就会自动对应数组对象。
使用数组
数组的访问与修改
1
2
3
4
5
int[] arr = {10, 20, 30};
System.out.println(arr[0]); // 访问第一个元素,输出10
arr[1] = 200; // 修改第二个元素为200
System.out.println(arr.length); // 输出3(数组长度)
// System.out.println(arr[3]); // 报错:ArrayIndexOutOfBoundsException
数组的遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int[] arr = {1,2,3};
// 1. 普通for循环(适合需要索引的场景)
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 2. 增强for循环(简洁,无索引)
for (int num : arr) {
System.out.println(num);
}
// 3. Arrays.forEach(函数式风格)
Arrays.forEach(arr, num -> System.out.println(num));
数组的复制、扩容、排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int[] arr = {1,2,3};
// 1. 数组复制(System.arraycopy:手动指定源/目标、起始位置、长度)
int[] newArr1 = new int[5];
System.arraycopy(arr, 0, newArr1, 0, arr.length); // 把arr复制到newArr1的前3位
// newArr1 = [1,2,3,0,0]
// 2. 数组扩容(Arrays.copyOf:自动创建新数组,指定新长度)
int[] newArr2 = Arrays.copyOf(arr, 6); // 扩容到长度6,默认值补0
// newArr2 = [1,2,3,0,0,0]
// 3. 数组排序(Arrays.sort:原地排序,默认升序)
int[] unsortedArr = {3,1,2};
Arrays.sort(unsortedArr);
// unsortedArr = [1,2,3]
Java 没有 “真正的多维数组”,只有 “数组的数组”
很多人误以为 int[][] 是 “二维数组”,但 Java 本质上不存在连续内存的多维数组,所谓的 “多维数组” 只是「一维数组的嵌套」(数组的数组)—— 外层数组的每个元素是另一个数组的引用,而非直接存储多维数据。
1. 本质:“多维数组” 的内存布局
以 int[][] arr2d 为例,内存结构是两层嵌套:
- 第一步:arr2d = new int[2][]; → 创建外层一维数组对象(长度 2),每个元素是 int[] 类型的引用(初始为 null);
![img_1.png]()
- 第二步:arr2d[0] = new int[3]; arr2d[1] = new int[4]; → 为外层数组的每个引用指向内层一维数组对象(长度可不同)
![img_2.png]()
2. 两种 “多维数组” 创建方式(规则 vs 不规则)
(1)规则 “二维数组”(伪多维)
看似是二维数组,实则是外层数组的每个元素指向长度相同的内层数组:
1
2
3
4
// 简化写法:创建2行3列的“二维数组”(外层长度2,内层每个长度3)
int[][] arr2d = new int[2][3];
arr2d[0][1] = 10; // 外层第0个引用 → 内层数组第1个元素赋值
System.out.println(arr2d[0][1]); // 输出10
(2)锯齿数组(不规则数组,体现 “数组的数组” 本质)
1
2
3
4
5
6
7
8
9
// 第一步:创建外层数组(长度3,元素为int[]引用,初始null)
int[][] jaggedArr = new int[3][];
// 第二步:为每个外层元素指向不同长度的内层数组
jaggedArr[0] = new int[2]; // 第0行:2列
jaggedArr[1] = new int[5]; // 第1行:5列
jaggedArr[2] = new int[1]; // 第2行:1列
jaggedArr[1][3] = 20; // 第1行第3列赋值20
System.out.println(jaggedArr[1][3]); // 输出20


