Что такое Java-эквивалент этого метода отражения C#?

Я переписываю фреймворк, изначально созданный на C#, на Java, и это меня озадачило. Это метод, использующий отражение для возврата любого свойства в классе, который реализует определенный интерфейс с помощью LINQ:

public List<TInterface> GetElementsOfType<TInterface>()
{
    return GetType().GetProperties()
        .Where(x => typeof(TInterface).IsAssignableFrom(x.PropertyType))
        .Select(x => x.GetValue(this, null)).OfType<TInterface>()
        .ToList();
}

Я пытаюсь воссоздать на Java, и пока это есть. Не слишком уверен, правда ли это ?:

public <T> List<?> GetElementsOfType(Class<T> klazz) {
    Class<?> props = this.getClass();
    List<T> elementsOfType = new ArrayList<>();
    try {
            Field fieldlist[] = props.getDeclaredFields();
            for (Field aFieldlist : fieldlist) {
                if (aFieldlist.getType().isAssignableFrom(klazz)){
                    elementsOfType.add((T)aFieldlist);
                }
            }
    } catch (Exception e) {
            return null;
    }
    return elementsOfType;
}

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

@SuppressWarnings("unchecked")
public <T> List<T> GetElementsOfType(Class<T> klazz) {
    Class<?> props = this.getClass();
    List<T> elementsOfType = new ArrayList<>();
        try {
            Field fieldlist[] = props.getDeclaredFields();
            for (Field aFieldlist : fieldlist) {
                if (klazz.isAssignableFrom(aFieldlist.getType())){
                    elementsOfType.add((T) aFieldlist.get(this));
                }
            }   
        } catch (Exception e) {
          return elementsOfType;
        }

    return elementsOfType;
    }
}

если вы используете java 8, вы можете посмотреть потоки java 8, он может в значительной степени делать то же самое, что и версия C# выше

BrokenFrog 04.10.2018 17:45

Да, использую Java 8, в потоки не смотрел

Phonesis 04.10.2018 17:58

Вы хотите, чтобы аргументы для isAssignableFrom были в том же порядке, что и в C#

Peter Lawrey 04.10.2018 18:32
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
569
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В Java свойство - это не поле. Свойство определяется как общедоступный нестатический метод чтения и, если это свойство не предназначено только для чтения, как общедоступный нестатический метод записи. Экземпляр класса с одним или несколькими такими свойствами называется Java-компонентом.

Вы можете проверить свойства с помощью пакета java.beans, начиная с Интроспектор:

try {
    BeanInfo beanInfo = Introspector.getBeanInfo(props, Object.class);

    for (PropertyDescriptor prop : beanInfo.getPropertyDescriptors()) {
        if (klazz.isAssignableFrom(prop.getPropertyType())) {
            elementsOfType.add(klazz.cast(prop.getReadMethod().invoke(this)));
        }
    }
} catch (IntrospectionException | ReflectiveOperationException e) {
    throw new RuntimeException(e);
}

Поскольку Java использует проверенные исключения, в этом случае вы не сможете легко использовать Streams для написания LINQ-подобного кода. Можно, но громоздко. И не стоит заморачиваться, учитывая, что приведенный выше код довольно лаконичен.

(Причина использования Object.class в Introspector.getBeanInfo(klazz, Object.class) заключается в том, что нам не нужны свойства объекта, а именно свойство class объекта только для чтения, определенное в Object.getClass ().)

К сожалению, это просто каждый раз вызывает IntrospectionException. Любые идеи? Я называю это так: List <Editable> editableElements = bingHomePage.GetElementsOfType (Editable.class);

Phonesis 05.10.2018 12:41

В чем заключается сообщение об исключении IntrospectionException? Содержит ли его трассировка стека какие-либо разделы «Причина»?

VGR 05.10.2018 15:43

Думаю, это может быть связано с этим stackoverflow.com/questions/4438815/…

Phonesis 05.10.2018 15:57

Эта ошибка, по-видимому, связана с наличием методов get и set в разных классах иерархии наследования. Это верно для вашего класса реквизита? В противном случае более вероятно, что исключение на самом деле сообщает вам, в чем проблема.

VGR 05.10.2018 16:21

Спасибо, да, у меня возникают проблемы с чтением банкомата трассировки стека (с использованием кода VS и похоже, что там есть какая-то проблема), но это звучит примерно правильно. Хорошие новости. Теперь он работает, используя мой исходный код (см. Обновление), но я обязательно попытаюсь его реорганизовать, чтобы ваш подход заработал.

Phonesis 05.10.2018 16:29

Другие вопросы по теме