488. Java 反射 - 动态创建数组
在日常代码里,我们通常这样创建数组:
java
int[] numbers = new int[10];
但在 反射 API 中,我们也可以使用 java.lang.reflect.Array 类来动态创建任意类型、任意维度的数组。这在 运行时才知道类型和大小 的场景中非常有用(例如框架、序列化、数据映射等)。
1. 使用 Array.newInstance() 创建数组
下面的代码演示了如何用反射创建一个长度为 10 的 int 数组,并对其进行操作:
java
int length = 10;
// 创建一个 int[10]
Object o = Array.newInstance(int.class, 10);
// 判断是否为数组
boolean isArray = o.getClass().isArray();
System.out.println("isArray = " + isArray);
// 获取数组的元素类型
Class<?> componentType = o.getClass().getComponentType();
System.out.println("componentType = " + componentType);
// 获取数组长度
int reflectiveLength = Array.getLength(o);
System.out.println("reflectiveLength = " + reflectiveLength);
// 给数组赋值
for (int i = 0; i < reflectiveLength; i++) {
Array.set(o, i, 2 * i);
}
// 打印数组内容
System.out.println(Arrays.toString((int[]) o));
输出结果:
java
isArray = true
componentType = int
reflectiveLength = 10
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
📌 逐行解释:
Array.newInstance(int.class, 10)→ 创建int[10]o.getClass().isArray()→ 确认对象o的类型确实是数组o.getClass().getComponentType()→ 得到数组元素类型(这里是int)Array.getLength(o)→ 动态获取数组长度Array.set(o, i, 2*i)→ 给第i个元素赋值
2. 避免装箱与拆箱
Array 类提供了专门针对 基本类型 的 get/set 方法,比如:
Array.getInt(Object array, int index)/Array.setInt(Object array, int index, int value)Array.getDouble(Object array, int index)/Array.setDouble(Object array, int index, double value)
👉 使用这些方法可以避免 装箱(boxing)/拆箱(unboxing) 的性能开销。
⚠️ 注意事项:
- 如果调用
Array.setFloat()但传入Float对象而不是float,会抛IllegalArgumentException。 - 宽类型转换允许,例如:
Array.setInt()可以操作long[](因为int→long是安全的拓宽转换)。 - 但反过来不行,
Array.setLong()不能操作int[],因为可能丢失精度。
3. 越界访问
就像普通数组一样,如果你尝试访问超出数组长度的索引,会抛出:
java
java.lang.ArrayIndexOutOfBoundsException
4. 扩展:多维数组
反射也支持 多维数组,例如:
java
// 创建一个 3x3 的二维数组
Object matrix = Array.newInstance(int.class, 3, 3);
// 设置 [1][2] 元素
Array.set(Array.get(matrix, 1), 2, 99);
System.out.println(Arrays.deepToString((int[][]) matrix));
输出:
java
[[0, 0, 0], [0, 0, 99], [0, 0, 0]]
🎯 总结
- ✅
Array.newInstance()→ 动态创建数组(支持多维) - ✅
Array.getLength()→ 获取数组长度 - ✅
Array.get()/Array.set()→ 读写数组元素(Object 版本) - ✅
Array.getInt()/Array.setInt()等 → 基本类型高效访问 - ⚠️ 注意装箱/拆箱,以及宽化/窄化转换规则