2016-04-26 79 views
0

我有這樣的兩個階級,我想,第二個(DocumentiDiIdentitaList)創建一個基於在第一類中聲明的變量的所有值的列表(DocumentiDiIdentita反思級Java

其實我得到這個代碼

public class DocumentiDiIdentita { 

    public static final String CARTA_IDENTITA = "CI"; 
    public static final String CARTA_IDENTITA_AFTER_25_06_2003 = "CI_NEW"; 
    public static final String PASSAPORTO_CONSOLATO = "PC"; 
    public static final String PASSAPORTO_QUESTURA = "PQ"; 
    public static final String PASSAPORTO_ESTERO = "PE"; 
    public static final String PATENTE_MORIZZAZIONE = "PZ"; 
    public static final String PATENTE_PREFETTURA = "PT"; 
    public static final String PORTOARMI = "PM"; 
    public static final String PASSAPORTO="PA"; 

} 

public static class DocumentiDiIdentitaList { 
    private static Field[] fields = DocumentiDiIdentita.class.getFields(); 
    public static List documentTypes = Arrays.asList(fields); 

} 

但實際上列表documentTypes cointains變量的名稱,而不是它們的值,所以實際上是:

CARTA_IDENTITA 
CARTA_IDENTITA_AFTER_25_06_2003 
PASSAPORTO_CONSOLATO 
etc. 

,但我想:

CI 
CI_NEW 
PC 
etc. 

我怎麼能做到這一點? (我必須在Java 1.4上運行)

+2

Field.get(Object)呢? http://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html#get-java.lang.Object- – JEY

+0

@JEY使這個答案;) – 2016-04-26 07:56:37

+0

我不能得到如何使用這個「Field.get(Object)」,對不起 – RudiDudi

回答

2

Java Reflections API允許您在元模型(即類,方法,字段等)上以編程方式操作哪些是您的代碼的結構信息,這意味着當您獲得對Field實例,它指的是由類聲明的字段,而不是類實例(又名對象)字段的實例。

爲了使用反射來獲取字段的值,您必須使用field.get(instance)來讀取給定實例的值。在靜態字段和方法的情況下,實例就是類本身。但是你不能傳遞類,因爲.class是一個擁有自己的字段和方法的對象,所以field.get(DocumentiDiIdentita.class)將不起作用。相反,對於訪問靜態值,您通過null作爲參數。

在Java 1.4及以上,你可以做

Field[] fields = DocumentiDiIdentita.class.getFields(); 
List documentTypes = new ArrayList(); 
for(int i = 0; i < fields.length; i++){ 
    Field f = fields[i]; 
    documentTypes.add(f.get(null)); 
} 

由於Java 5,你可以使用泛型和for-each循環:

Field[] fields = DocumentiDiIdentita.class.getFields(); 
List<String> documentTypes = new ArrayList<String>(); 
for(Field f : fields){ 
    documentTypes.add(f.get(null)); 
} 

在Java8你可以使用流

List docTypes = Stream.of(DocumentiDiIdentita.class.getFields()).map(this::uncheckedGet).collect(Collectors.toList()); 

private Object uncheckedGet(Field f) { 
    try { 
     return f.get(null); 
    } catch (IllegalAccessException e) { 
     throw new RuntimeException(e); 
    } 
} 

爲了便於閱讀,我省略了上述java 1.4和1.5例子的異常處理。您可以使用java 8示例的uncheckedGet方法替換field.get調用,或重新使用異常處理。

+0

不幸的是我不得不使用1.4 – RudiDudi

+0

@RudiDudi - 可悲的是,我也想提出一個類似的代碼。你能說出爲什麼這不適用於JDK 1.4嗎?我無法安裝JDK 1.4,儘管我擁有它。 – soufrk

+0

「令牌上的語法錯誤」;「,」列表documentTypes = new ArrayList();和「無法在字段f = fields.get(i);」上的數組類型Field []上調用get(int) – RudiDudi

-1

到達靜態字段值有點棘手。你需要傳遞null獲得方法是這樣的:

public class DocumentiDiIdentitaList { 

    public static void main(String[] args) { 

     Field[] fields = DocumentiDiIdentita.class.getDeclaredFields(); 

      Arrays.stream(fields).forEach(f -> { 

       try { 

        System.out.println(f.get(null)); 

       } 
       catch (IllegalAccessException e) {} 

      }); 
    } 
} 

希望我幫助:)

- 編輯

對不起java8版本:(你可以檢查是否得到法空值工作?

+0

不,是強制性的。8 java兼容級別 「lambda表達式只允許在源級1.8或更高」, 也Arrays.stream是1.8方法 – RudiDudi

+0

我相信op提及的問題,他使用Java 1.4,它不包含lambda。 – user902383