Java反射:类字段和方法的顺序是否标准化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1097807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:42:24  来源:igfitidea点击:

Java reflection: Is the order of class fields and methods standardized?

javareflectionstandards-compliance

提问by ivan_ivanovich_ivanoff

Using reflection on Java classes to access all field, methods, and so on:
Is there a standardized order of these elements(which is specified in some standard)?

使用 Java 类的反射来访问所有字段、方法等:
这些元素是否有标准化的顺序(在某些标准中指定)?

Of course, I couldcheck it empirically, but I need to know if it's always the same.

当然,我可以凭经验检查它,但我需要知道它是否总是相同的。

EDIT:
I waited for the question: What I need the order for ;)
Long story short: I have JAXB-annotated classes, and want no represent these classes visually. While the order of XML attributes is neither relevant for the XML standard, nor for JAXB, I want to have a certain order the XML attributes for the visual representation.
For example: start comes after end. This hurts one's intuition.

编辑:
我在等这个问题:我需要什么命令 ;)
长话短说:我有 JAXB 注释的类,并且不想在视觉上表示这些类。虽然 XML 属性的顺序与 XML 标准和 JAXB 都不相关,但我希望可视化表示的 XML 属性具有特定的顺序。
例如:开始在结束之后。这会伤害一个人的直觉。

采纳答案by Adam Paynter

According to the documentation:

根据文档

getFields()

getFields()

Returns an array containing Field objects reflecting all the accessible public fields of the class or interface represented by this Class object. The elements in the array returned are not sorted and are not in any particular order.This method returns an array of length 0 if the class or interface has no accessible public fields, or if it represents an array class, a primitive type, or void.

返回一个包含 Field 对象的数组,这些对象反映了此 Class 对象表示的类或接口的所有可访问公共字段。返回的数组中的元素没有排序,也没有任何特定的顺序。如果类或接口没有可访问的公共字段,或者它表示数组类、基本类型或 void,则此方法返回长度为 0 的数组。

getMethods()

getMethods()

Returns an array containing Method objects reflecting all the public member methods of the class or interface represented by this Class object, including those declared by the class or interface and those inherited from superclasses and superinterfaces. Array classes return all the (public) member methods inherited from the Object class. The elements in the array returned are not sorted and are not in any particular order.This method returns an array of length 0 if this Class object represents a class or interface that has no public member methods, or if this Class object represents a primitive type or void.

返回一个包含 Method 对象的数组,该对象反映了此 Class 对象表示的类或接口的所有公共成员方法,包括由类或接口声明的方法以及从超类和超接口继承的方法。数组类返回从 Object 类继承的所有(公共)成员方法。返回的数组中的元素没有排序,也没有任何特定的顺序。如果此 Class 对象表示没有公共成员方法的类或接口,或者此 Class 对象表示基本类型或 void,则此方法返回长度为 0 的数组。

回答by Nate

Even though getFields() and getMethods() return results in no particular order, you can add the elements in the returned arrays to collections, and provide your own Comparator to sort them however you want.

尽管 getFields() 和 getMethods() 返回的结果没有特定的顺序,但您可以将返回的数组中的元素添加到集合中,并提供您自己的 Comparator 以根据需要对它们进行排序。

In this example, I'm just sorting the fields and methods based on the alphabetical order of their names - but you could sort them based on declaring class, modifiers, return types, etc. by providing the required logic in the respective Comparator.

在此示例中,我只是根据名称的字母顺序对字段和方法进行排序 - 但您可以通过在相应的比较器中提供所需的逻辑,根据声明的类、修饰符、返回类型等对它们进行排序。

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

}

回答by akarnokd

A sample for my annotation based idea.

我的基于注释的想法的示例。

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

}