RudiDudi
RudiDudi

Reputation: 455

Reflection class java

I have this two classes and i want that the second one (DocumentiDiIdentitaList) creates a list based on all the values of the variables declared in the first class(DocumentiDiIdentita)

Actually i got this code

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

}

but actually the list documentTypes cointains the name of the variables, not their values, so actually is:

CARTA_IDENTITA
CARTA_IDENTITA_AFTER_25_06_2003
PASSAPORTO_CONSOLATO
etc.

but i want:

CI
CI_NEW
PC
etc.

how can i do this? (i have to run on java 1.4)

Upvotes: 0

Views: 141

Answers (2)

Gerald Mücke
Gerald Mücke

Reputation: 11132

The Java Reflections API allows you to operate programmatically on the meta model, i.e. classes, methods, fields etc. Which are the structural information of your code. Which mean, when you obtain access to a Field instance, it refers to the field declared by a class and not an instance of the field of an class instance (aka object).

In order to get the value of a field using reflection, you have to read the value for a given instance using field.get(instance). In case of static fields and methods, the instance is the class itself. But you cannot pass the class itself because the .class is an object with own fields and methods, so field.get(DocumentiDiIdentita.class) will not work. Instead, for accessing static values, you pass null as parameter.

In Java 1.4 and above you could do

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

Since Java 5 you could use generics and for-each loop:

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

In Java8 you could use streams

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

For the sake of readability I ommitted the Exception handling for both java 1.4 and 1.5 examples above. You may replace the field.get call with the uncheckedGet method of the java 8 example or the reuse the exception handling.

Upvotes: 2

viniolli
viniolli

Reputation: 219

It's a little bit tricky to get to the static field value. You need to pass null to get method like this:

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

            });
    }
}

Hope i helped:)

-- edit

Sorry for java8 version:( could you check if get method works with null value?

Upvotes: -1

Related Questions