
在 java 中声明对象数组(如 `student[] s = new student[3];`)仅创建了引用容器,数组元素默认为 `null`;必须显式调用 `new student()` 为每个索引位置实例化对象,否则调用 `s[i].setname(...)` 将抛出 nullpointerexception。
Java 中的对象数组本质上是对象引用的数组,而非对象本身的数组。当你执行:
Student[] s = new Student[3];
JVM 仅分配一个长度为 3 的引用容器,其中每个元素初始值均为 null —— 此时并未创建任何 Student 实例。若跳过实例化直接访问 s[0].setName("Alice"),就会触发 NullPointerException,错误信息明确指出:Cannot invoke "Student.setName(String)" because "s[i]" is null。
✅ 正确做法:在使用前逐个 new 出对象
应在循环中为每个索引显式创建实例,例如:
Scanner scanner = new Scanner(System.in);
Student[] students = new Student[3];
for (int i = 0; i < students.length; i++) {
students[i] = new Student(); // ✅ 关键:必须先实例化!
System.out.print("Enter Name: ");
students[i].setName(scanner.nextLine());
System.out.print("Enter ID: ");
students[i].setId(scanner.nextLine());
System.out.print("Enter Phone Number: ");
students[i].setPhoneNumber(scanner.nextInt());
scanner.nextLine(); // 消费换行符,避免 nextLine() 被跳过
}⚠️ 注意事项:
- 不要重复创建多个 Scanner:原代码中 new Scanner(System.in) 被多次调用(name、ID、phoneNumber),不仅资源冗余,还可能导致输入流异常。应共用一个 Scanner 实例。
- 数组越界风险:原代码声明 new Student[2] 却尝试访问 s[2](索引 2),超出合法范围 [0,1],将引发 ArrayIndexOutOfBoundsException。务必确保数组长度 ≥ 元素数量,并用 students.length 控制循环边界。
- nextInt() 后的换行符陷阱:nextInt() 不读取后续换行符,导致下一次 nextLine() 直接返回空字符串。建议在 nextInt() 后紧跟 scanner.nextLine() 清理缓冲区。
? 完整可运行示例(修复版):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final int N = 3;
Student[] students = new Student[N]; // 声明引用数组
Scanner sc = new Scanner(System.in);
for (int i = 0; i < N; i++) {
students[i] = new Student(); // ✅ 必须!为每个元素分配对象
System.out.print("Enter Name: ");
students[i].setName(sc.nextLine());
System.out.print("Enter ID: ");
students[i].setId(sc.nextLine());
System.out.print("Enter Phone Number: ");
students[i].setPhoneNumber(sc.nextInt());
sc.nextLine(); // 清理缓冲区
}
// 输出验证
for (int i = 0; i < N; i++) {
System.out.printf("Student %d: %s (ID: %s, Phone: %d)%n",
i + 1,
students[i].getName(),
students[i].getId(),
students[i].getPhoneNumber()
);
}
sc.close();
}
}? 总结:对象数组 ≠ 对象数组(含实例)。牢记口诀:“声明不等于创建,引用需手动 new”。每次访问 arr[i].method() 前,请确认 arr[i] != null —— 最稳妥的方式就是在赋值前执行 arr[i] = new Type()。










