Порядок полей, возвращаемых Class.getFields () - PullRequest
13 голосов
/ 04 марта 2011

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

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

Ответы [ 4 ]

8 голосов
/ 04 марта 2011

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

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

2 голосов
/ 24 ноября 2013

В моей 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
1 голос
/ 04 марта 2011

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

0 голосов
/ 26 февраля 2013

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

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

Подробнее см. В документации .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...