Java Reflection : 클래스 필드 및 방법의 순서가 표준화 되었습니까?
-
11-09-2019 - |
문제
Java 클래스에 반영을 사용하여 모든 필드, 방법 등에 액세스하십시오.
이러한 요소의 표준화 된 순서가 있습니까? (일부 표준에 지정된 것은 무엇입니까)?
당연히 나는 ~할 수 있었다 경험적으로 확인하지만 항상 동일인지 알아야합니다.
편집하다:
나는 질문을 기다렸다 : 나는 주문이 필요한 것;)
짧은 이야기 : JaxB-Nantated 클래스가 있으며이 수업을 시각적으로 대표하지 않기를 원합니다. XML 속성의 순서는 XML 표준이나 JAXB와 관련이 없지만 시각적 표현에 대한 XML 속성을 특정 순서로 원합니다.
예를 들어 : 시작이 끝난 후 시작됩니다. 이것은 직관을 아프게합니다.
해결책
에 따르면 문서:
getFields()
이 클래스 객체로 표시되는 클래스 또는 인터페이스의 모든 접근 가능한 공개 필드를 반영하는 필드 개체가 포함 된 배열을 반환합니다. 반환 된 배열의 요소는 정렬되지 않으며 특정 순서가 아닙니다. 이 메소드는 클래스 또는 인터페이스에 액세스 가능한 공개 필드가 없거나 배열 클래스, 기본 유형 또는 공극을 나타내는 경우 길이 0의 배열을 반환합니다.
getMethods()
클래스 또는 인터페이스에 의해 선언 된 것과 슈퍼 클래스 및 슈퍼 인터페이스에서 상속 된 것들을 포함 하여이 클래스 객체로 표시되는 클래스 또는 인터페이스의 모든 공개 멤버 메소드를 반영하는 메소드 개체가 포함 된 배열을 반환합니다. 배열 클래스 객체 클래스에서 상속 된 모든 (공개) 멤버 메소드를 반환합니다. 반환 된 배열의 요소는 정렬되지 않으며 특정 순서가 아닙니다. 이 메소드는이 클래스 객체가 공개 멤버 메소드가없는 클래스 또는 인터페이스를 나타내는 경우 또는이 클래스 객체가 기본 유형 또는 공극을 나타내는 경우 길이 0의 배열 0을 반환합니다.
다른 팁
주석 기반 아이디어를위한 샘플.
public class FiledOrder {
@Retention(RetentionPolicy.RUNTIME)
public @interface Order {
int value();
}
public class SomeClass {
@Order(value=2)
public int field1;
@Order(value=1)
public int field2;
// no annotation
public int field3;
@Order(value=1)
public void start() { }
@Order(value=2)
public void end() { }
}
/**
* @param args
*/
public static void main(String[] args) {
Field[] fields = SomeClass.class.getFields();
Arrays.sort(fields, new Comparator<Field>() {
@Override
public int compare(Field o1, Field o2) {
Order or1 = o1.getAnnotation(Order.class);
Order or2 = o2.getAnnotation(Order.class);
// nulls last
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());
}
});
for (Field f : fields) {
System.out.println(f.getName());
}
Method[] methods = SomeClass.class.getMethods();
Arrays.sort(methods, new Comparator<Method>() {
@Override
public int compare(Method o1, Method o2) {
Order or1 = o1.getAnnotation(Order.class);
Order or2 = o2.getAnnotation(Order.class);
// nulls last
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());
}
});
for (Method m : methods) {
System.out.println(m.getName());
}
}
}
getFields () 및 getMethods () 리턴 결과는 특정 순서가 아니더라도 반환 된 배열의 요소를 컬렉션에 추가하고 자신의 비교기를 제공하여 원하는대로 정렬 할 수 있습니다.
이 예에서는 이름의 알파벳 순서를 기반으로 필드와 메소드를 정렬하는 것입니다. 그러나 각 비교기에서 필요한 논리를 제공하여 클래스, 수정 자, 반환 유형 등을 선언하여 정렬 할 수 있습니다.
public void PrintClassData(Class c) {
Field[] fieldArray = c.getFields();
Method[] methodArray = c.getMethods();
SortedSet<Field> fields = new TreeSet<Field>(new FieldComparator());
fields.addAll(Arrays.asList(fieldArray));
SortedSet<Method> methods = new TreeSet<Method>(new MethodComparator());
methods.addAll(Arrays.asList(methodArray));
StringBuffer b = new StringBuffer("All About ");
b.append(c.getName());
b.append("\nFields:\n");
for(Field f : fields) {
b.append("\t");
b.append(Modifier.toString(f.getModifiers()));
b.append(" ");
b.append(f.getType());
b.append(" ");
b.append(f.getName());
b.append("\n");
}
b.append("\nMethods:\n");
for (Method m : methods) {
b.append("\t");
b.append(Modifier.toString(m.getModifiers()));
b.append(" ");
b.append(m.getReturnType());
b.append(" ");
b.append(m.getName());
b.append("( ");
for (Class param : m.getParameterTypes()) {
b.append(param.getName());
b.append(", ");
}
b.deleteCharAt(b.lastIndexOf(","));
b.append(")\n");
}
System.out.println(b.toString());
}
private static class FieldComparator implements Comparator<Field> {
public int compare(Field f1, Field f2) {
return (f1.getName().compareTo(f2.getName()));
}
}
private static class MethodComparator implements Comparator<Method> {
public int compare(Method m1, Method m2) {
return (m1.getName().compareTo(m2.getName()));
}
}