Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of Fields returned by Class.getFields()

Javadoc for Class.getFields() say: "The elements in the array returned are not sorted and are not in any particular order."

Any hints on how the order actually is determined? Is it possible that when I execute this method twice, I get fields in different order? In other words, is the order stable for given compiled class, or even between compilations of the same source file?

like image 660
Konrad Garus Avatar asked Mar 04 '11 16:03

Konrad Garus


3 Answers

It should be stable, and for Oracle's JVM its the order they are declared, but you should not rely on this.

You should base lookup on the field's name (and possibly declaring class) rather than position.

like image 124
Peter Lawrey Avatar answered Oct 21 '22 15:10

Peter Lawrey


On my JVM, at least,

Class.getFields() returns fields in declaration order.

Class.getMethods(), on the other hand, doesn't always. It returns them in (I believe) the order the classloader sees the strings. So if two classes have the same method name, the second-loaded class will return the shared method name before its other methods.

javap confirms the compiler wrote both fields and methods in declaration order.

See the output of this code sample.

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class OrderTest {
    public static void main(String[] args) {
        // fields are in declaration order
        for (Field field : C1.class.getDeclaredFields()) {
            System.out.println(field.getName());
        }
        for (Field field : C2.class.getDeclaredFields()) {
            System.out.println(field.getName());
        }

        // methods, on the other hand, are not necessarily in declaration order.
        for (Method method : C1.class.getDeclaredMethods()) {
            System.out.println(method.getName());
        }
        for (Method method : C2.class.getDeclaredMethods()) {
            System.out.println(method.getName());
        }
    }
}

class C1 {
    public int foo;
    public int bar;
    public int getFoo() { return foo; }
    public int getBar() { return bar; }
}

class C2 {
    public int bar;
    public int foo;
    public int getBar() { return bar; }
    public int getFoo() { return foo; }
}

on my JVM (1.7.0_45, Windows) this returns

foo
bar
bar
foo
getFoo
getBar
getFoo
getBar
like image 2
user3027400 Avatar answered Oct 21 '22 15:10

user3027400


Create a helper method that returns a sorted list, and use that instead whenever you need the list of fields. Or lookup by name instead of index.

like image 1
mellamokb Avatar answered Oct 21 '22 15:10

mellamokb