通过反射设置对象中ArrayList类型成员变量时遇异常求助
问题解决:反射修改ArrayList成员变量时的IllegalArgumentException
核心错误原因
你抛出的异常根源在于field.get(this.getClass())这行代码:
field.get(Object obj)方法中,实例字段需要传入类的实例对象,而你传入的this.getClass()返回的是Class<Person>对象(类本身),不是Person的实例,所以JVM无法在Class对象上获取属于实例的成员变量。
修复步骤及完整代码
1. 修正field.get()的参数
把field.get(this.getClass())改为field.get(this),传入当前类的实例(this)来获取实例字段的值。
2. 字段名比较改用equals()
字符串比较要用equals()而非==,避免因字符串引用不同导致匹配失败。
3. 结合注解处理泛型类型
利用@TableAnnotation获取列表的泛型实际类型,确保添加的元素类型符合要求。
修正后的完整方法代码
public void setMemberTable(List<Table> tables, String memberName) throws IllegalAccessException { for (Field field : getClass().getDeclaredFields()) { if (field.getName().equals(memberName)) { field.setAccessible(true); // 传入当前实例获取列表对象 List<?> list = (List<?>) field.get(this); // 读取注解获取泛型实际类型(可选,用于类型校验) TableAnnotation annotation = field.getAnnotation(TableAnnotation.class); if (annotation != null) { Class<?> targetType = annotation.type(); // 示例:校验tables中的元素是否符合注解指定的类型 for (Table table : tables) { if (targetType.isInstance(table)) { list.add(table); } } } else { // 无注解时直接添加(根据需求调整) list.addAll(tables); } // 找到目标字段后跳出循环,提升效率 break; } } }
关键改动说明
field.get(this):正确传入实例对象,获取当前实例的成员变量值。field.getName().equals(memberName):安全的字符串匹配方式。- 注解的使用:通过
field.getAnnotation(TableAnnotation.class)获取字段上的注解,进而拿到泛型的实际类型,实现类型安全的元素添加。
额外注意事项
- 如果是静态字段,
field.get()才需要传入null或者Class对象,但你的字段都是实例字段(非static),所以必须传入实例。 - 即使字段是private,
field.setAccessible(true)已经可以突破访问限制,不需要改成public(当然改成public也不影响,但没必要)。
内容的提问来源于stack exchange,提问作者jordanthompson
相关产品推荐
相关产品推荐

