특정 주석이있는 필드의 값을 가져와야하므로 반사를 통해이 Field Object를 얻을 수 있습니다. 문제는이 필드가 항상 비공개이지만 항상 getter 메소드가 있음을 알고 있습니다. getAc 메소드를 호출하는 것을 선호하지만 setAccesible (true)을 사용하고 값을 가져올 수 있다는 것을 알고 있습니다 (PermissionManager가 없을 때).
“get + fieldName”을 검색하여 메소드를 찾을 수 있음을 알고 있습니다 (예를 들어 부울 필드의 경우 “is + fieldName”이라고도 함).
이 getter를 호출하는 더 좋은 방법이 있는지 궁금합니다 (많은 프레임 워크가 getters / setter를 사용하여 다른 방식으로 속성에 액세스합니다).
감사
답변
이것이 올바른 방향으로 당신을 가리켜 야한다고 생각합니다.
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));
}
Introspector를 사용하지 않고 BeanInfo 또는 PropertyDescriptor 인스턴스를 직접 작성할 수 있습니다. 그러나 Introspector는 일반적으로 Good Thing ™ 인 내부에서 일부 캐싱을 수행합니다. 캐시 없이도 행복하다면
// 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는 다른 편리한 것들과 함께 제공됩니다. 즉, 사용자 입력에서 속성 설정을 단순화하기 위해 즉석 값 변환 (객체에서 문자열로, 문자열에서 객체로).
답변
이를 위해 Reflections 프레임 워크를 사용할 수 있습니다
import static org.reflections.ReflectionUtils.*;
Set<Method> getters = ReflectionUtils.getAllMethods(someClass,
withModifier(Modifier.PUBLIC), withPrefix("get"), withAnnotation(annotation));
답변
이름 지정 규칙은 잘 설정된 JavaBeans 스펙 의 일부이며 java.beans 패키지 의 클래스에서 지원됩니다 .
답변
리플렉션을 호출하고 주석을 통해 값에 대한 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