发布于2026-07-08 阅读(0)
扫一扫,手机访问
Ja va反射创建数组的关键是安全存取异构数据:用Array.newInstance()创建运行时类型数组,原始类型须用int.class等;混合类型用Object[]+Class[]元信息封装;原始数组需用Array.getXXX/setXXX访问,动态容器应封装类型校验与装箱转换。

Ja va 反射中创建数组对象本身不是难事,但真要拿它去封装异构数据结构——比如运行时才知道元素类型和长度、混合了字符串和日期的那种“脏数据”——关键就在于如何绕过泛型擦除、正确处理原始类型、统一访问接口,还得避免一不留神抛出 ArrayStoreException 或 IllegalArgumentException。说白了,核心不是“造一个数组”,而是“让这个数组能安全存、可统一读、适配未知类型”。
Array.newInstance() 创建运行时确定类型的数组这是最直接的路子,适用于已知组件类型(Class 对象)和长度的场景:
String.class、MyBean.class 即可int.class、boolean.class(不能用 Integer.class),否则抛 IllegalArgumentExceptionArray.newInstance(int.class, 3, 4) 创建 3×4 的 int[][]来个例子:
Class> elementType = String.class;int length = 5;Object arr = Array.newInstance(elementType, length); // 返回 Object,实际是 String[]Array.set(arr, 0, "hello"); // 安全写入String s = (String) Array.get(arr, 0); // 安全读取
Object[] 作为底层容器 + 类型元信息如果元素类型在运行时才动态混合——比如一行数据同时包含 String、Double、LocalDateTime——那就别拿泛型数组硬扛(T[] 这条路走不通)。更务实的做法是:
Object[] 存储所有值(它能容纳任意引用类型)Class[] 或 Type[] 数组,记录每个位置的实际逻辑类型这样既规避了原始类型无法放入 Object[] 的问题(自动装箱会搞定),又保留了类型语义,后续序列化或校验时也不会迷路。
反射创建的原始类型数组,不能拿 Object[] 的方式去访问——因为它们压根不是 Object 的子类。必须用 Array.getXXX() / Array.setXXX() 系列方法:
Array.getInt(arr, i)、Array.setBoolean(arr, i, true)arr.getClass().getComponentType().isPrimitive()),再分发到对应方法(int[]) arr 是合法的,但 (Object[]) arr 对原始数组会直接 ClassCastException一个实用的异构容器(比如 DynamicRow)可以这样搭:
private final Object array;(存储反射创建的数组)private final Class> componentType;(记录真实组件类型)Class> type, int len,调用 Array.newInstance(type, len) T get(int i, Class expected) ,内部校验类型兼容性并转换toString() 和 toArray() 时注意原始类型需先转包装类数组(如 int[] → Integer[])这种设计不依赖泛型数组,不破坏类型安全,而且能自然支持 JSON 序列化——Jackson 完全可以识别 Object[] 里的内容。
上一篇:并发编程中的伪共享(False Sharing):分析 @Contended 注解如何通过内存对齐隔离变量缓存行
下一篇:ReentrantLock 调试技巧:利用 getQueuedThreads() 与 getHoldCount() 监控锁的持有情况
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8