如何通过Reflection API获取顺序一致的字段类型与字段值列表
问题原因
Java语言规范并没有规定getDeclaredFields()、getDeclaredMethods()返回元素的顺序,不同JDK版本、不同编译参数都可能导致返回顺序变化,两者的排序逻辑也没有关联,分别遍历生成两个列表自然无法保证顺序一致。
正确实现思路
以字段遍历的顺序为基准,遍历每个字段时,根据字段名匹配对应的getter方法,同时收集字段值和方法返回类型,就能保证两个列表顺序完全一致。
修复后代码
import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import javax.persistence.Id; public class MethodFieldOrder { public static void main(String[] args) { Student entity = new Student(); entity.setGroupId(1); entity.setFirstName("Jackson"); entity.setLastName("Romanovich"); List<String> valuesToInsert = new ArrayList<>(); List<String> returnTypes = new ArrayList<>(); Field[] fields = entity.getClass().getDeclaredFields(); for (Field field : fields) { // 过滤带@Id注解的字段,代替硬编码remove(0),逻辑更可靠 if (field.isAnnotationPresent(Id.class)) { continue; } field.setAccessible(true); try { // 收集字段值 Object value = field.get(entity); valuesToInsert.add(value.toString()); // 按字段名匹配对应getter方法 String fieldName = field.getName(); String getterName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); Method getter; // 布尔类型字段特殊处理,优先匹配is前缀的getter if (field.getType() == boolean.class || field.getType() == Boolean.class) { try { String isGetterName = "is" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); getter = entity.getClass().getDeclaredMethod(isGetterName); } catch (NoSuchMethodException e) { getter = entity.getClass().getDeclaredMethod(getterName); } } else { getter = entity.getClass().getDeclaredMethod(getterName); } // 收集返回类型 returnTypes.add(String.valueOf(getter.getReturnType())); } catch (Exception e) { e.printStackTrace(); } } System.out.println("Values to insert : " + valuesToInsert); System.out.println("RETURN TYPES : " + returnTypes); } }
额外优化建议
- 可以提前缓存字段和getter的对应关系,多次调用时避免重复反射匹配,提升性能
- 建议增加字段无对应getter的异常兜底处理,兼容不规范的实体类定义
内容的提问来源于stack exchange,提问作者Mary
相关产品推荐
相关产品推荐

