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 meth开发者_JAVA技巧od 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?
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.
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
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.
An natural order of properties offers the Ujorm framework with its key-value objects using the readKeys() method. Each item of the result have got similar features like the Field including reading and writting values from/to the object. For example see the next code:
public class User extends AbstractUjo implements Serializable {
/** Factory */
private static final KeyFactory<User> f = newFactory(User.class);
/** Keys: */
public static final Key<User, Long> PID = f.newKey();
public static final Key<User, Integer> CODE = f.newKey();
public static final Key<User, String> NAME = f.newKey();
public static final Key<User, Double> CASH = f.newKey();
static {
f.lock();
}
// Setters:
public void setPid(Long pid) {
PID.setValue(this, pid);
}
public void setCode(Integer code) {
CODE.setValue(this, code);
}
public void setName(String name) {
NAME.setValue(this, name);
}
public void setCash(Double cash) {
CASH.setValue(this, cash);
}
// Getters ...
}
The natural order of keys can be iterated by:
for (Key key : new User().readKeys()) {
System.out.println("Key: " + key);
}
See the documentation for more information.
精彩评论