2011-03-04 31 views
12

Javadoc對於Class.getFields()說:「返回的數組中的元素沒有排序並且沒有任何特定順序。」Class.getFields()返回的字段順序

關於如何確定訂單的任何提示?當我執行這個方法兩次時,我有可能得到不同順序的字段嗎?換句話說,對於給定的編譯類,甚至是在同一個源文件的編譯之間,順序是否穩定?

+6

爲什麼會出現爲了此事向你的代碼?關鍵是,不要假定任何關於排序,因爲沒有保證。 – 2011-03-04 16:30:26

+1

不值得冒這個險......假設他們每次都是隨機的,並且在防守方面進行編碼。 – skaffman 2011-03-04 16:31:09

+1

@skaffman,你甚至不能假定它是隨機的。 ;) – 2011-03-04 16:32:54

回答

8

它應該是穩定的,並且對於Oracle的JVM它的聲明順序,但不應該依賴於它。

您應該根據字段的名稱(可能聲明類)而不是位置進行查找。

1

創建一個幫助器方法,該方法返回一個排序列表,並在需要列表的字段時使用它。或者按名稱而不是索引查找。

0

屬性的自然順序使用readKeys()方法提供Ujorm framework及其鍵值對象。 結果的每個項目都具有類似的功能,如字段包括讀取和寫入對象的值。例如參見下一個代碼:

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

更多信息,請參見documentation

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