news 2026/9/3 22:00:00

5. Java 数组核心知识点

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5. Java 数组核心知识点

一、数组概述

1.1 什么是数组

数组是相同数据类型元素的有序集合,使用一个变量名管理多个同类型数据。本质是一个固定长度的容器。

1.2 核心特点

特点

说明

类型统一

数组中所有元素必须是同一数据类型(如全部 int 或全部 String)

长度固定

数组一旦创建,长度不可修改。length属性记录当前长度

有序性

元素按索引(下标)排列,索引从 0 开始

引用类型

数组是引用数据类型,数组名存储的是堆内存地址而非元素本身

1.3 存储逻辑

数组在内存中占据连续的存储空间。以int[] arr = {10, 20, 30}为例,堆内存中开辟 3 个连续的 int 空间(每个 4 字节),索引 0 对应 10、索引 1 对应 20、索引 2 对应 30。通过「数组名 + 索引」即可 O(1) 定位任意元素。


二、数组的初始化

2.1 静态初始化

创建数组时直接指定元素值,长度由元素个数自动推断。适用于已明确所有元素值的场景。

三种写法:

// 写法1:简化版(推荐) 数据类型[] 数组名 = {元素1, 元素2, 元素3, ...}; // 写法2:完整版 数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, ...}; // 写法3:声明与初始化分离 数据类型[] 数组名; 数组名 = new 数据类型[]{元素1, 元素2, ...};

示例:

int[] intArr = {10, 20, 30, 40}; String[] strArr = {"Java", "数组", "静态初始化"}; boolean[] boolArr = {true, false, true};

注意事项:

规则

说明

禁止同时指定长度

new int[3]{1,2,3}编译错误,静态初始化长度由元素个数自动计算

元素必须有默认值

静态初始化时元素已显式赋值,不存在默认值概念;默认值仅出现在动态初始化中

写法3 不推荐

声明与初始化分离容易忘记赋值导致空指针

2.2 动态初始化

先指定数组长度,元素后续赋值。未赋值的元素使用对应类型的默认值。

语法:

数据类型[] 数组名 = new 数据类型[长度];

示例:

int[] arr = new int[3]; // 长度为 3,元素默认值均为 0 arr[0] = 10; arr[1] = 20; // arr[2] 未赋值,仍为默认值 0

各类型默认值:

数据类型

默认值

byte / short / int / long

0

float / double

0.0

boolean

false

char

'\u0000'(空字符)

引用类型(String、自定义类等)

null

2.3 静态 vs 动态初始化

维度

静态初始化

动态初始化

语法

int[] arr = {1,2,3};

int[] arr = new int[3];

元素来源

创建时直接指定

先定长度,后逐个赋值

适用场景

已知所有元素值

元素值待计算或批量填充

默认值

无(已显式赋值)

有(各类型默认值)


三、数组的访问与遍历

3.1 通过索引访问元素

int[] arr = {10, 20, 30}; // 读取 int first = arr[0]; // 10 // 修改 arr[1] = 200; // 索引 1 改为 200

索引合法范围:0 ~ arr.length - 1。超出范围抛出ArrayIndexOutOfBoundsException

3.2 两种遍历方式

int[] arr = {10, 20, 30, 40}; // 方式1:普通 for 循环(可获取索引、可修改元素) for (int i = 0; i < arr.length; i++) { System.out.println("索引" + i + ": " + arr[i]); } // 方式2:增强 for 循环(foreach,JDK 1.5+) for (int num : arr) { System.out.println(num); }

维度

普通 for

增强 for

可获取索引

可修改元素

是(通过索引赋值)

否(num 是副本)

代码简洁度

一般

适用场景

需要索引或修改元素的场景

仅遍历读取

3.3 经典练习题

求和:

int[] arr = {1, 2, 3, 4, 5}; int sum = 0; for (int num : arr) { sum += num; } System.out.println(sum); // 15

查找最大值:

int[] arr = {12, 45, 9, 78, 33}; int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } System.out.println(max); // 78

反转(双指针法):

int[] arr = {1, 2, 3, 4, 5}; int left = 0, right = arr.length - 1; while (left < right) { int temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; left++; right--; } // 结果: {5, 4, 3, 2, 1}

四、数组的内存原理

理解数组在 JVM 内存中的存储方式,是排查空指针和引用传递问题的前提。

4.1 JVM 内存分区(简化)

内存区域

存储内容

特点

虚拟机栈(Stack)

局部变量、方法调用栈帧、数组名(引用)

线程私有,方法结束即销毁

堆(Heap)

数组对象、类的实例对象

线程共享,由 GC 回收

方法区(Method Area)

类的元数据、静态变量、常量池

线程共享,JDK 8 后称元空间

数组涉及的核心区域:栈(存引用)+ 堆(存实体)

4.2 逐行拆解

以下代码的内存变化:

int a = 10; int[] arr; arr = new int[3]; arr[0] = 20; arr[1] = 30; arr = new int[2];

阶段

栈(main 栈帧)

int a = 10;

a = 10, arr = null

arr = new int[3];

a = 10, arr = 0x0011

地址 0x0011: {length:3, [0]=0, [1]=0, [2]=0}

arr[0] = 20; arr[1] = 30;

a = 10, arr = 0x0011

地址 0x0011: {length:3, [0]=20, [1]=30, [2]=0}

arr = new int[2];

a = 10, arr = 0x4455

地址 0x4455: {length:2, [0]=0, [1]=0};地址 0x0011 成为垃圾对象,等待 GC

关键结论:arr = new int[2]将引用指向新数组后,旧数组失去引用成为垃圾对象。

4.3 内存图示意

栈区(Stack) 堆区(Heap) ┌─────────────┐ ┌──────────────────┐ │ a = 10 │ │ 地址 0x4455 │ │ arr = 0x4455│────────→ │ int[] length=2 │ └─────────────┘ │ [0]=0 [1]=0 │ └──────────────────┘ ┌──────────────────┐ │ 地址 0x0011 (垃圾) │ │ int[] length=3 │ │ [0]=20 [1]=30 [2]=0│ └──────────────────┘

4.4 核心知识点

  • 数组名是栈中的引用变量,存储堆地址,而非数组本身
  • 所有数组元素(无论基本类型还是引用类型)都存储在堆中
  • 数组创建后未赋值时,元素使用各类型默认值
  • 引用指向新地址后,原数组若无其他引用,将被 GC 回收
  • 基本类型变量(如int a)的值直接存在栈中;数组引用变量存的是堆地址

五、常见异常与避坑指南

5.1 ArrayIndexOutOfBoundsException(索引越界)

原因:访问的索引不在0 ~ length-1范围内。

int[] arr = {1, 2}; System.out.println(arr[2]); // 异常:长度为 2,最大索引为 1

避免方式:遍历时始终使用i < arr.length作为循环条件。

5.2 NullPointerException(空指针)

原因:数组引用为 null,却尝试访问元素。

int[] arr = null; System.out.println(arr[0]); // 异常:arr 未指向任何堆内存空间

避免方式:确保数组已完成初始化(new 或静态赋值)后再访问。

5.3 引用传递的副作用

多个引用指向同一数组时,通过任一引用修改元素都会影响所有引用:

int[] arr1 = {1, 2}; int[] arr2 = arr1; // arr2 和 arr1 指向同一数组 arr2[0] = 100; System.out.println(arr1[0]); // 输出 100

需要独立副本时,应使用clone()System.arraycopy()

5.4 数组地址值

直接打印数组名会输出地址标识:

int[] arr = {10, 20, 30}; System.out.println(arr); // 输出如 [I@7852e922 // [ 表示数组,I 表示 int 类型,@ 后为哈希值

六、面试高频考点

Q1:int[] arr = new int[3]; System.out.println(arr.length);输出什么?

输出3length是数组对象的属性,存储在堆中,通过引用读取。

Q2:int[] arr = null; arr[0] = 10;会怎样?

抛出NullPointerException。arr 为 null,没有指向堆中的数组,无法访问元素。

Q3:基本类型变量和数组引用变量的区别?

基本类型变量(如int a = 10)的值直接存储在栈中;数组引用变量(如int[] arr)的值是堆地址,真正的数组数据在堆中。

Q4:静态初始化能同时指定长度吗?

不能。new int[3]{1, 2, 3}会编译错误。静态初始化的长度由元素个数自动计算。

Q5:int[] a = {10}; int[] b = a; b[0] = 20;a[0]是多少?

20。a 和 b 指向同一个堆数组,修改 b[0] 等价于修改同一块内存。


总结速查

主题

核心要点

数组本质

相同类型、固定长度、有序集合、引用类型

静态初始化

int[] arr = {1,2,3};直接给元素,长度自动计算

动态初始化

int[] arr = new int[3];先定长度,元素有默认值

元素访问

arr[index],索引范围 0 ~ length-1

遍历

普通 for(灵活) / 增强 for(简洁)

内存模型

栈存引用地址,堆存数组实体

常见异常

索引越界、空指针、引用传递副作用

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 21:57:51

YOLOv8实例分割实战:甲骨文拓片单字自动分割与识别全流程解析

简介&#xff1a;本资源是一套基于YOLOv8实现的甲骨文原始拓片图像单字级分割与识别完整项目&#xff0c;面向人工智能、计算机视觉及相关专业本科生、研究生及初学者&#xff0c;解决古文字图像中单字定位难、标注成本高、模型适配性弱等实际问题&#xff0c;适用于毕业设计、…

作者头像 李华
网站建设 2026/9/3 21:53:34

用Flask和SQLite从零搭建房源信息展示与发布系统

同样一套房源信息&#xff0c;扔到业主群、朋友圈是纯文字&#xff0c;过几天就刷没了&#xff1b;整理成一个网页或者小系统&#xff0c;不仅自己好维护&#xff0c;别人看着也清楚。今天就用 Flask 加 SQLite&#xff0c;带大家从零搭一个房源信息展示与发布小系统&#xff0…

作者头像 李华
网站建设 2026/9/3 21:47:52

欧卡2宝马M4 G82 MOD安装全攻略:从版本适配到排错实战

玩《欧洲卡车模拟2》的老玩家应该都有这种体会&#xff1a;开着卡车在高速上巡航久了&#xff0c;总想换换口味&#xff0c;在同一个欧洲世界里体验一把性能轿跑的感觉。正因如此&#xff0c;车辆类MOD一直是欧卡社区最热门的方向之一。本文围绕2022款宝马M4 G82 Competition&a…

作者头像 李华
网站建设 2026/9/3 21:41:48

合成工作流排查指南:从素材体检到导出校验的稳定输出方法

做创意合成这行&#xff0c;最常听到的牢骚是“明明时间线上看着挺好&#xff0c;一导出全毁了”。MONTAGEM 这个词放到中文语境里&#xff0c;既可以指短视频剪辑里的卡点混剪&#xff0c;也可以指音视频工程里的多层合成&#xff0c;而“DEAD WRONG”描述的正是那种最要命的状…

作者头像 李华
网站建设 2026/9/3 21:40:18

104.C 语言字节对齐:从底层原理到工程实践的完整指南

在嵌入式开发、系统编程和跨平台通信中&#xff0c;sizeof(struct)的结果往往不等于成员变量大小之和&#xff0c;这背后的核心原因就是字节对齐。作为 C 语言面试的高频考点&#xff0c;字节对齐不仅涉及 CPU 硬件的底层设计&#xff0c;还直接影响程序的性能、内存占用和跨平…

作者头像 李华
网站建设 2026/9/3 21:39:47

PyTorch+LSTM实现高速车辆轨迹预测实战方案

简介&#xff1a;本资源是一套基于PyTorch实现的高速公路车辆轨迹预测完整项目&#xff0c;面向计算机、人工智能及相关专业本科生&#xff0c;特别适用于毕业设计、课程设计及期末大作业场景。项目采用LSTM深度学习模型处理NGSIM真实交通数据集&#xff0c;完成多步车辆轨迹建…

作者头像 李华