根据属性名称动态调用Get方法

时间:2021-05-26 04:39:36

标签: java lombok

我有一个龙目岛课程

@Data
public class A {
  private long exp;
  private String id;
  private String code;

  ...about 50 more properties

}

并从类 A 创建一个实例,命名为 a,并使用一些值对其进行初始化。我将如何对属性执行 for 循环并调用方法 a.get(PropertyName)(基于属性名称)来提取值?

1 个答案:

答案 0 :(得分:2)

反射 API 是您的朋友。假设有以下类:

@Data
@AllArgsConstructor
public static class MyObject {
    private long id;
    private String name;
    private boolean active;
}

声明的字段访问

最简单的方法是直接读取声明的字段,因为您可以使用名称字段。

@SneakyThrows
@SuppressWarnings({"unchecked"})
public static <T> T get(String fieldName, Object instance, Class<?> instanceClass) {
    return (T) instanceClass.getDeclaredField(fieldName).get(instance);
}
MyObject myObject = new MyObject(1L, "John", true);
String name = get("name", myObject, MyObject.class);
System.out.println(name); // John
  • 优点:您可以直接使用字段名称
  • 缺点:您需要转换为字段类型。您需要处理 NoSuchFieldExceptionIllegalAccessException,如果不需要,您不应依赖反射。同样,当您直接访问该字段时,getter 方法将被忽略。

获取访问

事情有点复杂,因为 boolean 可以出现在声明的字段中,因为 getter 被称为 isActive 而不是 getActive,因此您需要处理这种情况:

@SneakyThrows
@SuppressWarnings({"unchecked"})
public static <T> T get(String fieldName, Object instance, Class<?> instanceClass) {
    String fieldNameBase = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    try {
        return (T) instanceClass.getDeclaredMethod("get" + fieldNameBase).invoke(instance);
    } catch (NoSuchMethodException ex) {
        return  (T) instanceClass.getDeclaredMethod("is" + fieldNameBase).invoke(instance);
    }
}
MyObject myObject = new MyObject(1L, "John", true);
boolean active = get("active", myObject, MyObject.class);
System.out.println(active); // true
  • 优点:保证调用 getter
  • 缺点:与之前的方式相同而且实现方式稍微复杂一些

免责声明:这不是可用于生产的代码,您可能需要执行一些异常处理。但是,我希望我的回答能让您了解如何处理它。


编辑:如果您不喜欢 Lombok 添加到 isboolean 前缀,您可以使用 lombok.getter.noIsPrefix 属性禁用它。在 Lombok: Configuration system 阅读更多内容。