通过反射调用吸气剂的最佳方式

Jav*_*avi 122 java reflection getter

我需要获取具有特定注释的字段的值,因此使用反射我可以获得此字段对象.问题是这个字段将永远是私有的,虽然我事先知道它总是有一个getter方法.我知道我可以使用setAccesible(true)并获取其值(当没有PermissionManager时),但我更喜欢调用其getter方法.

我知道我可以通过查找"get + fieldName"找到该方法(虽然我知道例如布尔字段有时被命名为"is + fieldName").

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

谢谢

sfu*_*ger 228

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

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));
}
Run Code Online (Sandbox Code Playgroud)

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

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

但是,有很多库可以扩展和简化java.beans API.Commons BeanUtils是一个众所周知的例子.在那里,你只需:

Object value = PropertyUtils.getProperty(person, "name");
Run Code Online (Sandbox Code Playgroud)

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

  • 很好地调用了 Apache 的 BeanUtils。使属性的获取/设置更容易,并处理类型转换。 (2认同)
  • PropertyDescriptor 的问题是它需要具有该属性的 getter 和 setter,并且您可能不希望拥有其中的一些。 (2认同)

小智 20

您可以使用Reflections框架

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


Mic*_*rdt 5

命名约定是完善的JavaBeans规范的一部分,由java.beans包中的类支持。