数组是 Java 中用于存储固定大小相同类型元素的容器,在数据处理和遍历场景中应用广泛。正确初始化数组是使用数组的基础,而数组越界是操作数组时最易出现的错误之一。掌握数组的初始化方法及越界问题的解决思路,对编写稳定的 Java 代码至关重要。
一、Java 数组的初始化方法
Java 数组初始化的核心是确定数组长度和为元素赋值,常见方式有以下三种:
(一)静态初始化
在声明数组的同时直接指定元素值,数组长度由元素个数自动确定,语法格式为:
数据类型 [] 数组名 = {元素 1, 元素 2, ..., 元素 n};
示例:
// 初始化整数数组,包含3个元素,长度为3int[] scores = {90, 85, 95};// 初始化字符串数组,包含2个元素,长度为2String[] names = {"张三", "李四"};
静态初始化的特点是简洁直观,适合元素数量少且值已知的场景,无需手动指定长度,避免长度与元素数不匹配的问题。
(二)动态初始化
先指定数组长度,再通过索引为元素赋值,语法格式为:
数据类型 [] 数组名 = new 数据类型 [长度];
示例:
// 初始化长度为5的整数数组,元素默认值为0int[] numbers = new int[5];// 为数组元素赋值(索引从0开始)numbers[0] = 10;numbers[1] = 20;// 未赋值的元素保持默认值(int类型默认0,对象数组默认null)
动态初始化适合元素数量确定但值需后续计算的场景(如从用户输入或文件中读取数据),数组元素会被自动赋予默认值(数值类型为 0,布尔类型为 false,引用类型为 null)。
(三)结合 new 关键字的静态初始化
静态初始化的另一种写法,显式使用new关键字,语法格式为:
数据类型 [] 数组名 = new 数据类型 []{元素 1, 元素 2, ..., 元素 n};
示例:
double[] weights = new double[]{65.5, 70.2, 58.9};
这种方式与第一种静态初始化功能相同,区别在于可在表达式中使用(如作为方法参数传递),而第一种写法仅能用于变量声明。
二、数组越界的原因及解决方法
数组越界(ArrayIndexOutOfBoundsException)是指访问数组时使用的索引超出了有效范围(有效索引为0到数组长度-1),是 Java 中最常见的运行时错误之一。
(一)数组越界的常见原因
索引计算错误:手动计算索引时出现偏差,如误将长度当作最大索引。
示例(错误):
int[] arr = {1, 2, 3};System.out.println(arr[3]); // 数组长度为3,最大索引为2,索引3越界
循环遍历边界错误:循环条件中使用<=代替<,导致索引超出最大范围。
示例(错误):
int[] arr = new int[5];for (int i = 0; i <= arr.length; i++) { // arr.length为5,i=5时越界 arr[i] = i;}
动态索引未校验:使用用户输入或动态计算的索引时,未判断是否在有效范围内。
示例(错误):
Scanner scanner = new Scanner(System.in);int index = scanner.nextInt();int[] arr = {10, 20};System.out.println(arr[index]); // 若用户输入2,索引越界
(二)解决数组越界的核心方法
明确数组索引范围:牢记数组索引从0开始,最大索引为数组名.length - 1,遍历数组时循环条件应使用< 数组名.length。
正确示例:
int[] arr = {1, 2, 3};for (int i = 0; i < arr.length; i++) { // 使用< arr.length,避免越界 System.out.println(arr[i]);}
使用增强 for 循环(foreach):无需手动控制索引,自动遍历所有元素,从根源上避免越界。
示例:
String[] fruits = {"苹果", "香蕉"};for (String fruit : fruits) { // 增强for循环,无需索引 System.out.println(fruit);}
索引使用前校验:对动态生成的索引(如用户输入、随机数),先判断是否在0到数组长度-1之间,再进行访问。
示例:
int[] arr = new int[4];int index = getIndexFromUser(); // 从用户输入获取索引if (index >= 0 && index < arr.length) { // 校验索引合法性 System.out.println(arr[index]);} else { System.out.println("索引越界,请输入0到3之间的数字");}
异常捕获处理:在无法提前校验的场景(如复杂计算的索引),使用try-catch捕获越界异常,避免程序崩溃。
示例:
int[] arr = {10, 20};try { System.out.println(arr[2]); // 可能越界的操作} catch (ArrayIndexOutOfBoundsException e) { System.out.println("发生数组越界:" + e.getMessage()); // 执行补救措施,如使用默认值}
三、数组初始化与使用的注意事项
数组长度固定:初始化后长度不可改变,若需动态调整大小,应使用ArrayList等集合类。
避免创建过大数组:动态初始化时若指定过大长度(如new int[1000000]),可能导致内存溢出。
多维数组初始化:二维数组需分别初始化外层和内层数组,如int[][] matrix = new int[3][]; matrix[0] = new int[4];。
Java 数组的初始化需根据元素是否已知选择静态或动态方式,而避免数组越界的核心是严格控制索引范围,结合循环条件校验、增强 for 循环和异常处理等手段,可有效提升代码的健壮性。初学者应养成 “先判断索引合法性,再操作数组” 的习惯,减少运行时错误。