Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically return a list of all class variable values in Java

Tags:

java

I am creating a helper class in parsing XML elements, so the developer do not need to know the exact name and capitalization of the XML fields.

private static class TagNames{
      public static String RESOURCE_ID = "ResourceId";
      public static String RESOURCE_NAME = "ResourceName";
      public static String RESOURCE_PRICE = "ResourcePrice";
}

This makes it easier to do things like:

someXMLParser.getValueByTagName(TagNames.RESOURCE_ID);

My question is this. If I want to iterate over all the fields declared in class TagNames, how do I do that? Pseudocode:

For tag in TagNames:
   someXMLParser.getValueByTagName(tag)

I know I will probably have to restructure all of this. But I can't figure out a way to make the names easily accessible as well as iterable, without any duplication.

Any suggestions?

like image 242
SpongeBob Avatar asked Oct 17 '25 22:10

SpongeBob


2 Answers

You're literally asking for a solution based on reflection, but I think a Java Enum may be a better choice in this case. Building on Frederick's example:

public class EnumTest {
    public enum Tags {
        RESOURCE_ID("ResourceId"), 
        REOURCE_NAME("ResourceName"), 
        RESOURCE_PRICE("ResourcePrice");

        private final String tagName;
        Tags(String tagName) {
            this.tagName = tagName;
        }

        public String getTagName() {
            return tagName;
        }
    }

    public static void main(String[] args) {
        for(Tags tag : Tags.values()) {
            System.out.println("const:" + tag.name() 
                    + " tagName:" + tag.getTagName());
        }
        // API user might do e.g.:
        // document.getValueForTag(Tags.REOURCE_NAME);
    }
}
like image 71
Mike Clark Avatar answered Oct 20 '25 13:10

Mike Clark


Although I agree that you should probably use enums or ResourceBundles, here's a solution to your actual question. A method that generates a Map name -> value from all public constants in a given class (the only thing that's missing should be try / catch or throws)

public static Map<String, Object> getConstantValues(Class<?> clazz){

    Map<String, Object> constantValues = new LinkedHashMap<String, Object>();
    for(Field field : clazz.getDeclaredFields()){
        int modifiers = field.getModifiers();
        if(Modifiers.isPublic(mod)
            && Modifiers.isStatic(mod) && Modifiers.isFinal(mod)){
            constantValues.put(field.getName(), field.get(null));
        }
    }
    return constantValues;
}
like image 42
Sean Patrick Floyd Avatar answered Oct 20 '25 13:10

Sean Patrick Floyd