Подтвердить что ты не робот

Порядок полей, возвращаемых Class.getFields()

Javadoc для Class.getFields() скажет: "Элементы возвращаемого массива не отсортированы и не находятся в каком-либо конкретном порядке".

Какие-либо намеки на то, как определяется порядок? Возможно ли, что, когда я выполняю этот метод дважды, я получаю поля в другом порядке? Другими словами, стабилен порядок для данного скомпилированного класса или даже между компиляциями одного и того же исходного файла?

4b9b3361

Ответ 1

Он должен быть стабильным, а для Oracle JVM - его порядок, который они объявлены, но вы не должны полагаться на это.

Вы должны основывать поиск по имени поля (и, возможно, объявлению класса), а не положению.

Ответ 2

В моем JVM, по крайней мере,

Class.getFields() возвращает поля в порядке объявления.

Class.getMethods(), с другой стороны, не всегда. Он возвращает их в (я считаю) порядок, который класс загрузчик видит в строках. Поэтому, если два класса имеют одно и то же имя метода, второй загруженный класс возвращает имя общего метода перед другими его методами.

javap подтверждает, что компилятор написал оба поля и методы в порядке объявления.

См. вывод этого примера кода.

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

на моем JVM (1.7.0_45, Windows) это возвращает

foo
bar
bar
foo
getFoo
getBar
getFoo
getBar

Ответ 3

Создайте вспомогательный метод, который возвращает отсортированный список, и используйте его, когда вам нужен список полей. Или искать по имени вместо индекса.

Ответ 4

Естественный порядок свойств предлагает структуру Ujorm с его объектами с ключом, используя метод readKeys(). Каждый элемент результата имеет аналогичные функции, такие как поле, включая чтение и запись значений с/на объект. Например, см. Следующий код:

 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 ...
 }

Естественный порядок ключей можно повторить:

 for (Key key : new User().readKeys()) {
     System.out.println("Key: " + key);
 }

Дополнительную информацию см. в документации.