Есть ли библиотека, которая может дать мне все экземпляры класса, которые встречаются в другом классе? - PullRequest
2 голосов
/ 01 февраля 2012

У меня есть класс, который имеет несколько полей, которые являются подклассом другого класса.Я хочу быстро найти все экземпляры этого подкласса в классе верхнего уровня.

Например

public class TopClass {
 private ClassIWant1 myVar1;
 private ClassIWant2 myVar2;
 private OtherJunk myVar3;
 private Nested myVar4;
}

public class Nested {
 private ClassIWant3 myVar11;
}

public class SuperClass {
}

public ClassIWant1 extends SuperClass {}
public ClassIWant2 extends SuperClass {}
public ClassIWant3 extends ClassIWant1 {}

Если бы мне пришлось выполнить этот пример с экземпляром TopClass, я быожидаю получить список, содержащий значения для myVar1, myVar2 и myVar11.

У меня есть общее представление о том, как использовать отражение, чтобы сделать это вручную, но я надеюсь, что мне не придется заново изобретатьколесо.Есть ли библиотека, которая может сделать это?

Я знаком с ReflectUtils , но я не уверен, может ли это сделать это или нет.

Ответы [ 2 ]

1 голос
/ 01 февраля 2012

Если я правильно понимаю ваш запрос, вы ищете что-то вроде этого:

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 с, если в полях они установлены в качестве значения. Я понятия не имею, что это будет делать с примитивными типами.

Отказ от ответственности: Код был кратко протестирован на оптимистичном примере, я не несу ответственности, если он вызовет ваш компьютер.

0 голосов
/ 01 февраля 2012

Является ли этот метод тем, что вы ищете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...