通过反射调用 getter 的最佳方式

2022-08-31 07:47:25

我需要获取具有特定注释的字段的值,因此通过反射,我能够获得此字段对象。问题是这个字段将始终是私有的,尽管我事先知道它总是有一个getter方法。我知道我可以使用setAccesible(true)并获取其值(当没有PermissionManager时),尽管我更喜欢调用其getter方法。

我知道我可以通过查找“get+fieldName”来查找该方法(尽管我知道例如布尔字段有时被命名为“is+fieldName”)。

我想知道是否有更好的方法来调用这个 getter(许多框架使用 getters/setter 来访问属性,所以也许他们以另一种方式这样做)。

谢谢


答案 1

我认为这应该为你指出正确的方向:

import java.beans.*

for (PropertyDescriptor pd : Introspector.getBeanInfo(Foo.class).getPropertyDescriptors()) {
  if (pd.getReadMethod() != null && !"class".equals(pd.getName()))
    System.out.println(pd.getReadMethod().invoke(foo));
}

请注意,您可以自己创建BeanInfo或PropertyDescriptor实例,即不使用Intramspector。但是,Introspector在内部进行了一些缓存,这通常是一件好事(tm)。如果你对没有缓存感到高兴,你甚至可以选择

// TODO check for non-existing readMethod
Object value = new PropertyDescriptor("name", Person.class).getReadMethod().invoke(person);

但是,有很多库可以扩展和简化java.beans API。Commons BeanUtils就是一个众所周知的例子。在那里,您只需执行以下操作:

Object value = PropertyUtils.getProperty(person, "name");

BeanUtils还附带了其他方便的东西。即动态值转换(对象到字符串,字符串到对象),以简化用户输入的属性设置。


答案 2

您可以使用反射框架来实现此目的

import static org.reflections.ReflectionUtils.*;
Set<Method> getters = ReflectionUtils.getAllMethods(someClass,
      withModifier(Modifier.PUBLIC), withPrefix("get"), withAnnotation(annotation));