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

时间:2010-04-14 15:14:54

标签: java reflection getter

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

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

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

由于

4 个答案:

答案 0 :(得分:218)

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

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实例,即不使用Introspector。但是,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附带其他方便的东西。即,即时值转换(对象到字符串,字符串到对象),以简化用户输入的设置属性。

答案 1 :(得分:18)

您可以使用Reflections框架

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

答案 2 :(得分:4)

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

答案 3 :(得分:2)

您可以调用反射,并通过注释设置值的getter序列顺序

public class Student {

private String grade;

private String name;

private String id;

private String gender;

private Method[] methods;

@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
    int value();
}

/**
 * Sort methods as per Order Annotations
 * 
 * @return
 */
private void sortMethods() {

    methods = Student.class.getMethods();

    Arrays.sort(methods, new Comparator<Method>() {
        public int compare(Method o1, Method o2) {
            Order or1 = o1.getAnnotation(Order.class);
            Order or2 = o2.getAnnotation(Order.class);
            if (or1 != null && or2 != null) {
                return or1.value() - or2.value();
            }
            else if (or1 != null && or2 == null) {
                return -1;
            }
            else if (or1 == null && or2 != null) {
                return 1;
            }
            return o1.getName().compareTo(o2.getName());
        }
    });
}

/**
 * Read Elements
 * 
 * @return
 */
public void readElements() {
    int pos = 0;
    /**
     * Sort Methods
     */
    if (methods == null) {
        sortMethods();
    }
    for (Method method : methods) {
        String name = method.getName();
        if (name.startsWith("get") && !name.equalsIgnoreCase("getClass")) {
            pos++;
            String value = "";
            try {
                value = (String) method.invoke(this);
            }
            catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                e.printStackTrace();
            }
            System.out.println(name + " Pos: " + pos + " Value: " + value);
        }
    }
}

// /////////////////////// Getter and Setter Methods

/**
 * @param grade
 * @param name
 * @param id
 * @param gender
 */
public Student(String grade, String name, String id, String gender) {
    super();
    this.grade = grade;
    this.name = name;
    this.id = id;
    this.gender = gender;
}

/**
 * @return the grade
 */
@Order(value = 4)
public String getGrade() {
    return grade;
}

/**
 * @param grade the grade to set
 */
public void setGrade(String grade) {
    this.grade = grade;
}

/**
 * @return the name
 */
@Order(value = 2)
public String getName() {
    return name;
}

/**
 * @param name the name to set
 */
public void setName(String name) {
    this.name = name;
}

/**
 * @return the id
 */
@Order(value = 1)
public String getId() {
    return id;
}

/**
 * @param id the id to set
 */
public void setId(String id) {
    this.id = id;
}

/**
 * @return the gender
 */
@Order(value = 3)
public String getGender() {
    return gender;
}

/**
 * @param gender the gender to set
 */
public void setGender(String gender) {
    this.gender = gender;
}

/**
 * Main
 * 
 * @param args
 * @throws IOException
 * @throws SQLException
 * @throws InvocationTargetException
 * @throws IllegalArgumentException
 * @throws IllegalAccessException
 */
public static void main(String args[]) throws IOException, SQLException, IllegalAccessException,
        IllegalArgumentException, InvocationTargetException {
    Student student = new Student("A", "Anand", "001", "Male");
    student.readElements();
}

}

排序后的输出

getId Pos: 1 Value: 001
getName Pos: 2 Value: Anand
getGender Pos: 3 Value: Male
getGrade Pos: 4 Value: A