Если я правильно понимаю ваш запрос, вы ищете что-то вроде этого:
public class Test {
public static void main(String[] args) {
TopClass top = …; // initialise as appropriate
System.out.println(findFields(top, SuperClass.class));
}
private static <T> List<T> findFields(Object haystack, Class<T> needle) {
return findFields0(haystack, needle, new HashSet<Object>(), new ArrayList<T>());
}
private static <T> List<T> findFields0(Object haystack, Class<T> needle, Set<Object> visited, List<T> result) {
if (visited.contains(haystack)) return result; // we already searched this object
visited.add(haystack);
for (Field field : haystack.getClass().getFields()) {
field.setAccessible(true);
Object fieldValue = null;
try {
fieldValue = field.get(haystack);
} catch (IllegalAccessException e) {
// shouldn't happen
throw new RuntimeException(e);
}
if (needle.isAssignableFrom(field.getType())) {
result.add(needle.cast(fieldValue));
}
// recurse
findFields0(fieldValue, needle, visited, result);
}
return result;
}
}
Это работает с использованием статических типов полей, как объявлено. То есть, если вы объявите поле как Object
, но оно содержит экземпляр SuperClass
или одного из его потомков, оно не будет найдено. Он также вернет null
с, если в полях они установлены в качестве значения. Я понятия не имею, что это будет делать с примитивными типами.
Отказ от ответственности: Код был кратко протестирован на оптимистичном примере, я не несу ответственности, если он вызовет ваш компьютер.