目录
- 前言
- 一、先学定义:数组的两种书写格式(推荐第一种)
-
- [1.1 推荐格式(直观、规范)](#1.1 推荐格式(直观、规范))
- [1.2 兼容格式(不推荐,仅了解)](#1.2 兼容格式(不推荐,仅了解))
- [1.3 关键提醒:定义≠初始化](#1.3 关键提醒:定义≠初始化)
- 二、静态初始化:直接往收纳盒里放数据(长度自动算)
-
- [2.1 语法格式(两种写法,都常用)](#2.1 语法格式(两种写法,都常用))
- [2.2 代码示例(新手重点练)](#2.2 代码示例(新手重点练))
- [2.3 核心特点](#2.3 核心特点)
- 三、动态初始化:先定收纳盒大小,再装数据(有默认值)
-
- [3.1 语法格式](#3.1 语法格式)
- [3.2 核心:数组的默认值规则(新手必记)](#3.2 核心:数组的默认值规则(新手必记))
- [3.3 代码示例(动态初始化 + 赋值 + 默认值验证)](#3.3 代码示例(动态初始化 + 赋值 + 默认值验证))
- [3.4 静态 vs 动态初始化](#3.4 静态 vs 动态初始化)
- [四、数组长度的获取:length 属性(不是方法!)](#四、数组长度的获取:length 属性(不是方法!))
-
- [4.1 代码示例](#4.1 代码示例)
- [4.2 新手避坑:别和 String 的 length () 搞混](#4.2 新手避坑:别和 String 的 length () 搞混)
- [五、新手必避的 4 个 "初始化致命坑"](#五、新手必避的 4 个 “初始化致命坑”)
-
- [5.1 坑 1:静态与动态初始化混用(最常见)](#5.1 坑 1:静态与动态初始化混用(最常见))
- [5.2 坑 2:未初始化直接使用数组](#5.2 坑 2:未初始化直接使用数组)
- [5.3 坑 3:索引越界(初始化后常见)](#5.3 坑 3:索引越界(初始化后常见))
- [5.4 坑 4:给数组赋值时类型不匹配](#5.4 坑 4:给数组赋值时类型不匹配)
- 总结
前言
上一节咱们搞懂了数组的核心概念 ------ 它是装同类型数据的 "整齐收纳盒"。但光知道概念没用,得学会 "怎么造这个收纳盒(定义数组)" 和 "怎么往里面装数据(初始化数组)":比如想装 5 个学生的成绩,是先定盒子大小再装数据,还是直接把成绩放进去让系统自动定大小?为什么刚造好的盒子里会有默认值?
这一节咱们就聚焦数组的 "创建 + 初始化",从定义格式(两种写法,推荐更规范的那种),到静态初始化(直接装数据)、动态初始化(先定大小再装),再到 length 属性获取长度,最后拆解新手最容易踩的初始化误区。
一、先学定义:数组的两种书写格式(推荐第一种)
定义数组就是 "声明要造一个什么样的收纳盒",Java 提供了两种合法格式,新手优先记推荐格式,更符合行业规范。
1.1 推荐格式(直观、规范)
java
数据类型[] 数组名;
-
示例:
java// 声明一个装int类型成绩的数组(收纳盒只装整数) int[] scores; // 声明一个装double类型价格的数组(收纳盒只装小数) double[] prices; // 声明一个装String类型姓名的数组(收纳盒只装字符串) String[] names; -
核心优势:
[]跟在数据类型后,一眼就能看出 "这是一个数组",比如int[]直接表示 "int 类型的数组",可读性更高。
1.2 兼容格式(不推荐,仅了解)
java
数据类型 数组名[];
-
示例:
java// 效果和int[] scores一样,但可读性差 int scores[]; -
为什么不推荐:这种写法是为了兼容 C/C++ 语法,
[]跟在数组名后,容易误以为 "scores 是 int 类型,后面加 [] 是补充",新手容易混淆。
1.3 关键提醒:定义≠初始化
新手容易犯的错:以为定义数组后就能直接用 ------ 比如int[] scores; scores[0] = 90;,这会编译报错!因为定义只是 "说要造盒子",还没真正创建盒子(分配内存),必须初始化后才能用。
二、静态初始化:直接往收纳盒里放数据(长度自动算)
静态初始化就是 "造盒子的时候直接把东西放进去",不用指定盒子大小,系统会根据你放的元素个数自动计算数组长度。
2.1 语法格式(两种写法,都常用)
写法 1(完整格式,清晰)
java
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ..., 元素n};
写法 2(简化格式,常用)
java
数据类型[] 数组名 = {元素1, 元素2, ..., 元素n};
2.2 代码示例(新手重点练)
java
public class ArrayStaticInit {
public static void main(String[] args) {
// 写法1:完整静态初始化(装3个学生成绩)
int[] scores1 = new int[]{90, 85, 95};
System.out.println("scores1的第1个成绩:" + scores1[0]); // 输出90
// 写法2:简化静态初始化(装4个商品价格)
double[] prices = {9.9, 19.9, 29.9, 39.9};
System.out.println("prices的第2个价格:" + prices[1]); // 输出19.9
// 装字符串的数组(静态初始化)
String[] names = {"张三", "李四", "王五"};
System.out.println("names的第3个姓名:" + names[2]); // 输出王五
}
}
2.3 核心特点
-
元素类型必须和数组类型一致:比如
int[]里不能装"90"(字符串),编译报错; -
长度由元素个数决定:比如
{90,85,95}有 3 个元素,数组长度就是 3,后续不能改; -
简化写法只能在声明时用:比如不能先定义再用简化写法,下面的代码会报错:
java// 错误示例:简化初始化只能和声明写在一起 int[] scores; scores = {90,85,95}; // 编译报错
三、动态初始化:先定收纳盒大小,再装数据(有默认值)
动态初始化就是 "先造一个指定大小的空盒子",暂时不装自定义数据,系统会给每个位置赋默认值,后续再手动赋值。
3.1 语法格式
java
数据类型[] 数组名 = new 数据类型[数组长度];
-
示例:
java// 造一个能装5个int类型成绩的空盒子(长度固定为5) int[] scores = new int[5];
3.2 核心:数组的默认值规则(新手必记)
刚动态初始化的数组,每个元素都有 "默认初始值",规则按数据类型分,记牢下面的表,避免误以为 "空盒子里啥都没有":
| 数据类型分类 | 具体类型 | 默认值 | 示例(int [5] 的默认值) |
|---|---|---|---|
| 整数类型 | byte/short/int/long | 0 | scores[0] = 0 |
| 浮点类型 | float/double | 0.0 | prices[0] = 0.0 |
| 字符类型 | char | '\u0000'(空字符,不是空格) | chars[0] = '\u0000' |
| 布尔类型 | boolean | false | flags[0] = false |
| 引用类型 | String / 数组 / 对象 | null(表示 "空",无指向) | names[0] = null |
3.3 代码示例(动态初始化 + 赋值 + 默认值验证)
java
public class ArrayDynamicInit {
public static void main(String[] args) {
// 1. 动态初始化:造一个长度为3的int数组(默认值都是0)
int[] scores = new int[3];
System.out.println("初始化后默认值:" + scores[0]); // 输出0
// 2. 手动给数组元素赋值
scores[0] = 90; // 第1个位置装90
scores[1] = 85; // 第2个位置装85
scores[2] = 95; // 第3个位置装95
// 3. 访问赋值后的元素
System.out.println("赋值后第1个成绩:" + scores[0]); // 输出90
// 验证引用类型数组的默认值(String数组)
String[] names = new String[2];
System.out.println("String数组默认值:" + names[0]); // 输出null
}
}
3.4 静态 vs 动态初始化
| 初始化方式 | 适用场景 | 核心特点 |
|---|---|---|
| 静态初始化 | 知道要装的所有元素值 | 直接赋值,长度自动算 |
| 动态初始化 | 只知道数组长度,元素值后续确定 | 先定长度,有默认值,后续手动赋值 |
-
例子:
-
装已知的 3 个成绩:用静态初始化
int[] scores = {90,85,95}; -
装 5 个还没统计的成绩:用动态初始化
int[] scores = new int[5],后续统计后再赋值。
-
四、数组长度的获取:length 属性(不是方法!)
数组创建后,能通过数组名.length获取长度(收纳盒的格子数),新手一定要注意:length是属性 ,不是方法,后面没有()。
4.1 代码示例
java
public class ArrayLength {
public static void main(String[] args) {
// 静态初始化:长度3
int[] scores = {90,85,95};
System.out.println("scores数组长度:" + scores.length); // 输出3
// 动态初始化:长度5
double[] prices = new double[5];
System.out.println("prices数组长度:" + prices.length); // 输出5
// 遍历数组(结合length)
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i+1) + "个成绩:" + scores[i]);
}
}
}
4.2 新手避坑:别和 String 的 length () 搞混
java
// 错误示例:数组用length(),编译报错
System.out.println(scores.length()); // 报错:找不到方法length()
// 正确对比:
String str = "Java";
System.out.println(str.length()); // 字符串是方法,带(),输出4
int[] arr = {1,2,3};
System.out.println(arr.length); // 数组是属性,不带(),输出3
五、新手必避的 4 个 "初始化致命坑"
5.1 坑 1:静态与动态初始化混用(最常见)
-
错误示例:既指定长度又直接赋值
java// 想同时指定长度3和元素{1,2,3},编译报错 int[] arr = new int[3]{1,2,3}; -
后果:编译报错!提示 "数组初始化器不是一个表达式";
-
解决方法:二选一:
java// 要么静态初始化(不指定长度) int[] arr = {1,2,3}; // 要么动态初始化(先指定长度,后续赋值) int[] arr = new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 3;
5.2 坑 2:未初始化直接使用数组
-
错误示例:只定义不初始化,直接赋值
java// 只声明数组,未创建/初始化 int[] scores; scores[0] = 90; // 编译报错:可能尚未初始化变量scores -
后果:编译报错!定义只是 "说要造盒子",还没真正分配内存;
-
解决方法:声明后立即初始化:
javaint[] scores = new int[5]; // 动态初始化 scores[0] = 90; // 正常赋值
5.3 坑 3:索引越界(初始化后常见)
-
错误示例:访问超出数组长度的索引
javaint[] arr = {1,2,3}; // 长度3,索引0/1/2 System.out.println(arr[3]); // 访问索引3,运行时报错 -
后果:运行时抛出
ArrayIndexOutOfBoundsException(数组索引越界),程序崩溃; -
解决方法:访问索引必须满足
0 ≤ 索引 < 数组长度,比如长度 3 的数组,索引只能是 0、1、2。
5.4 坑 4:给数组赋值时类型不匹配
-
错误示例:int 数组装字符串
javaint[] scores = new int[3]; scores[0] = "90"; // 编译报错:String无法转换为int -
后果:编译报错!数组只能装定义时指定类型的元素;
-
解决方法:赋值类型必须和数组类型一致:
javascores[0] = 90; // int类型,匹配
总结
这一节咱们掌握了数组定义与初始化的核心技能,记住 3 个核心点:
-
定义数组优先用
数据类型[] 数组名,更规范; -
初始化二选一:静态(直接装数据,长度自动算)、动态(先定长度,有默认值),不能混用;
-
获取长度用
数组名.length(属性,无括号),避免和字符串的 length () 混淆。
数组的初始化是使用数组的基础,掌握后就能真正把 "收纳盒" 造好并装数据。