views:

1062

answers:

3

Hello!

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)?

Of course, I could check 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.

+12  A: 

According to the documentation:

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.

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.

Adam Paynter
Thank you. That is sad, that no order is defined :(
ivan_ivanovich_ivanoff
No particular order, and no guarantees between different VMs and versions.
kd304
+2  A: 

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.

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

}
Nate
A: 

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

}
kd304