488. Java 反射 - 动态创建数组

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) 的性能开销。

⚠️ 注意事项:

  1. 如果调用 Array.setFloat() 但传入 Float 对象而不是 float,会抛 IllegalArgumentException。
  2. 宽类型转换允许,例如:Array.setInt() 可以操作 long[](因为 int → long 是安全的拓宽转换)。
  3. 但反过来不行,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() 等 → 基本类型高效访问
  • ⚠️ 注意装箱/拆箱,以及宽化/窄化转换规则
相关推荐
云浪9 小时前
Go源码分析:搞懂 Go 是如何实现堆的
后端·go·源码阅读
用户0333074139512 小时前
TypeScript using 与 AsyncDisposableStack:在真实服务端代码中协调多资源清理
前端
daisychey12 小时前
用 Playwright 做多平台内容分发,我踩过的 8 个坑
前端
调试人生的显微镜12 小时前
iOS开发入门:Interface Builder、基础控件及UITextField详解
后端·ios
泡海椒12 小时前
巡检照片与工单附件:jquick-pdf 图片嵌入的业务实战
后端
蜗牛互联网12 小时前
Python消费Responses SSE事件:增量文本、超时与取消
java·开发语言·人工智能·后端·python
AI持续学习12 小时前
文档权限变更如何回归测试?账号、空间、文件和分享链接用例清单
后端
谢亮_vipxieliang13 小时前
Go Worker Pool 设计——从原理到生产级实现
开发语言·后端·golang
IT_陈寒13 小时前
为什么你应该学习JavaScript?
前端·人工智能·后端
大龄秃头程序员13 小时前
iOS冷启动监控Demo
前端