You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java反射如何调用依赖类中匹配JsonProperty的getter/setter方法

答案

完全可以通过反射实现该需求,核心需要额外处理泛型集合类型的实际类型解析,你之前写的单类JsonProperty匹配逻辑可以直接复用,只需要补全嵌套类型、泛型类型的解析步骤即可。

实现思路

整体逻辑和你当前匹配MyClass字段的逻辑一致,只需要额外加两步处理:

  • 匹配到字段后先判断字段类型,如果是带泛型的集合类型(比如List<SecondClass>),通过Java反射的泛型API解析出集合元素的实际类型
  • 拿到嵌套类/集合元素类的Class对象后,复用相同的JsonProperty匹配逻辑,就能定位到对应类的字段、getter或setter方法

具体实现步骤

  • 先封装一个通用工具方法,输入目标Class和要匹配的JsonProperty值,返回匹配到的Field对象:
private Field getFieldByJsonProperty(Class<?> clazz, String jsonPropValue) {
    for (Field field : clazz.getDeclaredFields()) {
        JsonProperty annotation = field.getAnnotation(JsonProperty.class);
        if (annotation != null && annotation.value().equals(jsonPropValue)) {
            field.setAccessible(true);
            return field;
        }
    }
    throw new IllegalArgumentException("未找到对应JsonProperty的字段:" + jsonPropValue);
}
  • 针对你举的「先匹配my_list调用getMyList(),再匹配my_name调用setName()」的需求,实现代码如下:
public void accessNestedSetter(MyClass myClass, String newNameVal) throws Exception {
    // 1. 匹配MyClass中JsonProperty为my_list的字段
    Field myListField = getFieldByJsonProperty(MyClass.class, "my_list");
    // 2. 调用对应getter拿到List实例(等价于myClass.getMyList())
    String listGetterName = "get" + myListField.getName().substring(0,1).toUpperCase() + myListField.getName().substring(1);
    Method listGetter = MyClass.class.getMethod(listGetterName);
    List<SecondClass> myList = (List<SecondClass>) listGetter.invoke(myClass);
    // 按需处理空值:如果list为null就初始化后通过setter赋值回去
    if (myList == null) {
        myList = new ArrayList<>();
        String listSetterName = "set" + myListField.getName().substring(0,1).toUpperCase() + myListField.getName().substring(1);
        Method listSetter = MyClass.class.getMethod(listSetterName, List.class);
        listSetter.invoke(myClass, myList);
    }
    // 3. 解析List的泛型参数,拿到元素实际类型SecondClass
    ParameterizedType listGenericType = (ParameterizedType) myListField.getGenericType();
    Class<?> elementClass = (Class<?>) listGenericType.getActualTypeArguments()[0];
    // 4. 在SecondClass中匹配JsonProperty为my_name的字段
    Field nameField = getFieldByJsonProperty(elementClass, "my_name");
    // 5. 调用对应setter给每个元素赋值(等价于secondClass.setName(newNameVal))
    String nameSetterName = "set" + nameField.getName().substring(0,1).toUpperCase() + nameField.getName().substring(1);
    Method nameSetter = elementClass.getMethod(nameSetterName, String.class);
    for (SecondClass element : myList) {
        nameSetter.invoke(element, newNameVal);
    }
}

注意事项

  • 如果不需要严格遵循JavaBean规范调用getter/setter,可以直接通过Field.get()/Field.set()操作字段值,代码会更简洁,效果和调用getter/setter一致
  • 如果字段不是集合类型,是普通的嵌套对象(比如直接定义private SecondClass secondObj),不需要解析泛型,直接调用field.getType()就能拿到嵌套类的Class对象
  • 如果需要处理多层嵌套(比如SecondClass里还持有带@JsonProperty的第三层类对象),把上述匹配字段、解析类型的逻辑封装成递归方法即可
  • 调用setter或者直接给字段赋值时要注意类型匹配,比如my_name是String类型就传入字符串,其他类型需要提前做类型转换

内容的提问来源于stack exchange,提问作者mang4521

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:54:18