我有一个龙目岛课程
@Data
public class A {
private long exp;
private String id;
private String code;
...about 50 more properties
}
并从类 A 创建一个实例,命名为 a
,并使用一些值对其进行初始化。我将如何对属性执行 for 循环并调用方法 a.get(PropertyName)
(基于属性名称)来提取值?
答案 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
NoSuchFieldException
和 IllegalAccessException
,如果不需要,您不应依赖反射。同样,当您直接访问该字段时,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
免责声明:这不是可用于生产的代码,您可能需要执行一些异常处理。但是,我希望我的回答能让您了解如何处理它。
编辑:如果您不喜欢 Lombok 添加到 is
的 boolean
前缀,您可以使用 lombok.getter.noIsPrefix
属性禁用它。在 Lombok: Configuration system 阅读更多内容。