Отражение в Java: стандартизирован ли порядок полей и методов класса?

Использование отражения в классах Java для доступа ко всем полям, методам и т. Д.
Существует ли стандартизированный порядок этих элементов (который указан в каком-либо стандарте)?

Конечно, я мог бы проверить это эмпирически, но мне нужно знать, всегда ли это одно и то же.

РЕДАКТИРОВАТЬ:
Я ждал вопроса: для чего мне нужен заказ;)
Короче говоря: у меня есть JAXB-аннотированные классы, и я не хочу представлять эти классы визуально. Хотя порядок атрибутов XML не имеет отношения ни к стандарту XML, ни к JAXB, я хочу иметь определенный порядок атрибутов XML для визуального представления.
Например: начало идет после конца. Это вредит своей интуиции.

3 ответа

Решение

Согласно документации:

getFields()

Возвращает массив, содержащий объекты Field, отражающие все доступные открытые поля класса или интерфейса, представленные этим объектом Class. Элементы в возвращаемом массиве не отсортированы и расположены не в определенном порядке. Этот метод возвращает массив длины 0, если у класса или интерфейса нет доступных открытых полей или если он представляет класс массива, примитивный тип или void.

getMethods()

Возвращает массив, содержащий объекты Method, отражающие все открытые методы-члены класса или интерфейса, представленные этим объектом Class, включая те, которые объявлены классом или интерфейсом, и те, которые унаследованы от суперклассов и суперинтерфейсов. Классы Array возвращают все (публичные) методы-члены, унаследованные от класса Object. Элементы в возвращаемом массиве не отсортированы и расположены не в определенном порядке. Этот метод возвращает массив длины 0, если этот объект Class представляет класс или интерфейс, у которого нет открытых методов-членов, или если этот объект Class представляет примитивный тип или void.

Образец моей идеи, основанной на аннотациях.

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()));
    }

}
Другие вопросы по тегам