/* package whatever; // don't place package name! */

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.TreeSet;

/* Name of the class has to be "Main" only if the class is public. */
class Ideone {
	public static void main (String[] args) throws java.lang.Exception {
        System.out.println( "Keys1: " + new Keys1().keySet() );
        System.out.println( "Keys2: " + new Keys2().keySet() );
	}
}

class Keys1 {
    public static final ClassValue<TreeSet<String>> KEYS = new ClassValue<TreeSet<String>>() {
        @Override protected TreeSet<String> computeValue(Class<?> type) {
            final int desired=Modifier.PUBLIC|Modifier.STATIC|Modifier.FINAL;
            Field[] fields=type.getDeclaredFields();
            TreeSet<String> set = new TreeSet<>();
            for(Field f: fields) {
                if((f.getModifiers()&desired)==desired && f.getType()==String.class) try {
                    set.add((String)f.get(null));
                } catch(IllegalAccessException ex) {
                    throw new AssertionError(ex);
                }
            }
            for(Class<?> inner: type.getDeclaredClasses()) {
                set.addAll(get(inner));
            }
            type = type.getSuperclass();
            if(type != null && type != Object.class) set.addAll(get(type));
            return set;
        }
    };
    public TreeSet<String> keySet() {
        return KEYS.get(getClass());
    }

    public static final String AFIELD = "example";
}

// no additional steps required, the inherited keySet() does the job
class Keys2 extends Keys1 {
    public static final String ANOTHER_FIELD = "subclass example";

    static class Inner {
        public static final String FIELD = "innerclass example";
    }
}