0

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)

asked Apr 26, 2016 at 7:41
4
  • 2
    what about Field.get(Object) ? docs.oracle.com/javase/8/docs/api/java/lang/reflect/… Commented Apr 26, 2016 at 7:44
  • @JEY make that an answer ;) Commented Apr 26, 2016 at 7:56
  • I can't get how to use this "Field.get(Object), sorry. Commented Apr 26, 2016 at 8:15
  • @RudiDudi you are passing object which fields you want to get, or null if fields are static. Commented Apr 26, 2016 at 8:20

2 Answers 2

2

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.

answered Apr 26, 2016 at 8:16
Sign up to request clarification or add additional context in comments.

5 Comments

unfortunally i have to use 1.4
@RudiDudi - Sadly, I was also going to suggest a similar code. Can you tell why this doesn't work on JDK 1.4 ? I couldn't get JDK 1.4 installed, although I have it.
"Syntax error on token ";", { expected after this token" on "List documentTypes = new ArrayList();" and "Cannot invoke get(int) on the array type Field[]" on "Field f = fields.get(i);"
it's not fields.get(i) but fields[i] and documentTypes.add(f.get(null)); instead of list.add. You may have to catch/throw some exceptions.
sorry for the code typos, I didn't double check with the IDE, fixed it now, thanks for comments.
-1

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?

answered Apr 26, 2016 at 7:58

2 Comments

No, is mandatory 1.8 java compilance level "Lambda expressions are allowed only at source level 1.8 or above", also Arrays.stream is a 1.8 method
I believe op mention in question he is using Java 1.4, which does not contain lambda.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.