1. 基本概念与目标
什么是类数组
在 Java 中,类数组指的是用于存放同一类对象的引用的有序集合。每个元素都是对某个对象的引用,初始时默认值为 null,不是实际对象本身。此处强调 对象引用的内存布局 与基本数据类型数组的差异。
通过类数组,可以把同一类型的对象集中管理,便于遍历、访问属性和调用方法。与简单的原始类型数组相比,类数组需要显式地实例化每个元素,否则访问会抛出 NullPointerException。
本篇围绕 Java 类数组定义全攻略,系统讲解从创建到遍历的完整流程,帮助你快速上手并写出高效易读的代码。核心要点包括声明、初始化、遍历与安全性控制。
public class Person {
private String name;
private int age;
public Person(String name, int age) { this.name = name; this.age = age; }
public String getName() { return name; }
public int getAge() { return age; }
}
2. 基本语法与声明
声明与初始化语法
在 Java,定义对象数组的基本语法是 MyClass[] arr,并通过 new MyClass[n] 分配引用的存储空间。注意这并不会创建数组中的对象,而只是创建引用槽。
若使用的是自定义类,请确保在使用前为每个元素分配实例,否则你将遇到 NullPointerException。
此外,使用对象数组时,请关注 元素的默认值,以及在循环中避免重新分配容量。
public class Car {
private String model;
public Car(String model) { this.model = model; }
public String getModel() { return model; }
}
Car[] cars = new Car[3]; // 仅创建引用槽
cars[0] = new Car("Tesla Model S");
cars[1] = new Car("BMW i3");
cars[2] = new Car("Audi A4");
3. 从创建到初始化:如何创建类数组
分步初始化策略
要将类数组真正投入使用,需要逐个元素完成初始化,否则在遍历或访问时会出现空指针风险。可以用显式赋值,或借助循环进行批量初始化。
下面的示例展示了两种常用的初始化策略:手动逐个初始化,以及使用循环统一赋值。通过对比,你可以选择更符合场景的方式。
Person[] people = new Person[3];
// 手动逐个初始化
people[0] = new Person("Alice", 28);
people[1] = new Person("Bob", 32);
people[2] = new Person("Carol", 24);
// 使用循环批量初始化
for (int i = 0; i < people.length; i++) {
people[i] = new Person("User" + i, 20 + i);
}
4. 遍历类数组的常用模式
基本遍历与空值处理
遍历类数组时,先进行空值检查,再调用对象方法,避免 NullPointerException。两种常见的遍历方式是传统 for 循环和增强 for 循环。
在性能敏感场景下,传统 for 循环可让你精准控制索引;在代码简洁性上,增强 for 循环更易读。
// 传统 for 循环
for (int i = 0; i < people.length; i++) {
Person p = people[i];
if (p != null) {
System.out.println(p.getName() + " - " + p.getAge());
}
}
// 增强 for 循环(需要确保无 null,如果有可能为 null,请添加判空)
for (Person p : people) {
if (p != null) {
System.out.println(p.getName());
}
}
访问字段与方法示例
通过遍历,你可以方便地访问对象的字段和调用方法,例如输出姓名与年龄,或执行业务逻辑。请注意保持封装性,调用公共方法而非直接访问字段。
for (Person p : people) {
if (p != null) {
System.out.println(p.getName() + " 的年龄是 " + p.getAge());
// 例如调用对象方法
// p.someBehavior();
}
}
5. 进阶话题与坑点
多维类数组的定义与遍历
在 Java 中,类数组也可以是多维的,例如 Person[][] grid = new Person[3][4]。注意这是一个引用类型的数组数组,内部的每一行也需要初始化。
遍历多维数组时,同样要处理 空值与未初始化的行/列,通常需要两层循环进行检查和访问。
Person[][] grid = new Person[2][3];
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = new Person("P" + i + "-" + j, i + j);
}
}
泛型数组的替代方案
在 Java 中,泛型不能直接定义数组类型,例如 List<T>[] 的用法会带来类型安全问题。推荐的做法是使用泛型集合替代固定大小的对象数组。
常见方案是用 List<MyClass> 或者在需要随机访问时使用 ArrayList<MyClass>,而不是原始的对象数组。
import java.util.ArrayList;
import java.util.List;
class MyClass { /* ... */ }
List list = new ArrayList<>();
list.add(new MyClass());
list.add(new MyClass());
// 可以按需扩容,并且具备更多实用方法


