Если вы довольны несколько менее удобной формой
import com.google.common.base.Equivalence;
...
metaData.add(new MetaData(Person.class, Equivalence.equals(), "name", "John", "group", "SIGMA"));
самое простое решение, основанное только на Java, заключается в добавлении класса интроспективных экземпляров в метаданные, параметризации способа сравнения объектов (здесь я использовал Guava, вы также можете использовать простую Java 8 BiPredicate<T super Person>
) и указывать имена свойств.
При выполнении вы можете использовать java.beans.Introspector#getBeanInfo()
для обнаружения имени получателя и установщика (это самый безопасный способ преодоления различных неприятностей в Java Beans, таких как логические свойства, полностью прописные имена свойств и т. Д. - я рекомендую предпочесть его наполовину запеченные инструменты на основе замены строк) и вызывайте их соответствующим образом.
Вы можете дополнительно сократить вызов, используя
metaData.add(new MetaData<Person>(Equivalence.equals(), "name", "John", "group", "SIGMA"));
(класс может быть получен с использованием рефлекса отражения, известного как токен типа или литерал типа)
или создание собственного подкласса, такого как EqualsMetadata
или PersonMetadata
, вы получите идею.
В качестве альтернативы, вы можете вообще избежать (простого старого) отражения и определить все с помощью ссылок на методы:
metaData.add(new MetaData(Equivalence.equals(), Person::getName, Person::setName, "John", Person::getGroup, Person::setGroup, "SIGMA"));
, который длиннее, но безопаснее - вы можете убедиться, что аргументы John
и SIGMA
соответствуют типу getter и setter.
Чтобы реализовать это с помощью внешнего инструмента, я рекомендую взглянуть на mapstruct.org. Dozer также возможен, однако в нашем проекте мы переходим на mapstruct из-за производительности и философии, основанной на сгенерированном коде, который IMHO дает лучшее понимание того, что действительно происходит во время конвертации.