/* 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 {
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) {
Field[] fields
=type.
getDeclaredFields(); TreeSet<String> set = new TreeSet<>();
if((f.
getModifiers()&desired
)==desired
&& f.
getType()==String.
class) try { 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"; }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEubGFuZy5yZWZsZWN0LkZpZWxkOwppbXBvcnQgamF2YS5sYW5nLnJlZmxlY3QuTW9kaWZpZXI7CmltcG9ydCBqYXZhLnV0aWwuVHJlZVNldDsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUgewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uIHsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oICJLZXlzMTogIiArIG5ldyBLZXlzMSgpLmtleVNldCgpICk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCAiS2V5czI6ICIgKyBuZXcgS2V5czIoKS5rZXlTZXQoKSApOwoJfQp9CgpjbGFzcyBLZXlzMSB7CiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIENsYXNzVmFsdWU8VHJlZVNldDxTdHJpbmc+PiBLRVlTID0gbmV3IENsYXNzVmFsdWU8VHJlZVNldDxTdHJpbmc+PigpIHsKICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIFRyZWVTZXQ8U3RyaW5nPiBjb21wdXRlVmFsdWUoQ2xhc3M8Pz4gdHlwZSkgewogICAgICAgICAgICBmaW5hbCBpbnQgZGVzaXJlZD1Nb2RpZmllci5QVUJMSUN8TW9kaWZpZXIuU1RBVElDfE1vZGlmaWVyLkZJTkFMOwogICAgICAgICAgICBGaWVsZFtdIGZpZWxkcz10eXBlLmdldERlY2xhcmVkRmllbGRzKCk7CiAgICAgICAgICAgIFRyZWVTZXQ8U3RyaW5nPiBzZXQgPSBuZXcgVHJlZVNldDw+KCk7CiAgICAgICAgICAgIGZvcihGaWVsZCBmOiBmaWVsZHMpIHsKICAgICAgICAgICAgICAgIGlmKChmLmdldE1vZGlmaWVycygpJmRlc2lyZWQpPT1kZXNpcmVkICYmIGYuZ2V0VHlwZSgpPT1TdHJpbmcuY2xhc3MpIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgc2V0LmFkZCgoU3RyaW5nKWYuZ2V0KG51bGwpKTsKICAgICAgICAgICAgICAgIH0gY2F0Y2goSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbiBleCkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcihleCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZm9yKENsYXNzPD8+IGlubmVyOiB0eXBlLmdldERlY2xhcmVkQ2xhc3NlcygpKSB7CiAgICAgICAgICAgICAgICBzZXQuYWRkQWxsKGdldChpbm5lcikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHR5cGUgPSB0eXBlLmdldFN1cGVyY2xhc3MoKTsKICAgICAgICAgICAgaWYodHlwZSAhPSBudWxsICYmIHR5cGUgIT0gT2JqZWN0LmNsYXNzKSBzZXQuYWRkQWxsKGdldCh0eXBlKSk7CiAgICAgICAgICAgIHJldHVybiBzZXQ7CiAgICAgICAgfQogICAgfTsKICAgIHB1YmxpYyBUcmVlU2V0PFN0cmluZz4ga2V5U2V0KCkgewogICAgICAgIHJldHVybiBLRVlTLmdldChnZXRDbGFzcygpKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGZpbmFsIFN0cmluZyBBRklFTEQgPSAiZXhhbXBsZSI7Cn0KCi8vIG5vIGFkZGl0aW9uYWwgc3RlcHMgcmVxdWlyZWQsIHRoZSBpbmhlcml0ZWQga2V5U2V0KCkgZG9lcyB0aGUgam9iCmNsYXNzIEtleXMyIGV4dGVuZHMgS2V5czEgewogICAgcHVibGljIHN0YXRpYyBmaW5hbCBTdHJpbmcgQU5PVEhFUl9GSUVMRCA9ICJzdWJjbGFzcyBleGFtcGxlIjsKCiAgICBzdGF0aWMgY2xhc3MgSW5uZXIgewogICAgICAgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEZJRUxEID0gImlubmVyY2xhc3MgZXhhbXBsZSI7CiAgICB9Cn0=