Действительно ли возможно использовать дженерики при определении отображений в Orika?

Я знаю об этом стирании типа и предотвратил бы использование дженериков при определении сопоставлений, поскольку этот вопрос указывает как отображать универсальные объекты с помощью Orika?. Но Часто задаваемые вопросы по Orika в разделе Поддерживаются ли дженерики раздел, претензии:

Да. Orika включает специальную поддержку времени выполнения для сопоставления универсальных типов через специальный класс Type, который можно использовать для определения точных элементов типа шаблонного типа.

В идеале должно работать что-то вроде следующего (предположим, что мы можем каким-то образом поддерживать параметры класса во время выполнения с помощью некоторых функций Orika):

     mapperFactory.classMap(Asset<T,K>.class, AssetDto<K>.class)
    .maybeSomeCustomization...
    .byDefault()
    .register();

Мне не удалось найти ни одного примера использования класса Type<?> в часто задаваемых вопросах Orika.


person David Fernandez    schedule 17.02.2016    source источник
comment
Общие классы, например. Asset<T,K>.class не существует, поэтому вы не можете сделать это таким образом.   -  person Thomas    schedule 17.02.2016
comment
Да, нет, я хотел бы знать об альтернативах, как упоминается в часто задаваемых вопросах Orika.   -  person David Fernandez    schedule 17.02.2016


Ответы (2)


Можно, нужно использовать MapperFactory#classMap(Type<A>, Type<B>) API вместо MapperFactory#classMap(Class<A>, Class<B>).

Вы можете найти много примеров в тестах Orika в generics.

Чтобы создать экземпляр Type, вы можете использовать анонимный подкласс TypeBuilder на месте:

Type<MyGenericClass<GenericParam1, GenericParam2>> type =
    new TypeBuilder<MyGenericClass<GenericParam1, GenericParam2>>() {}.build();

Обратите внимание на скобки {} после конструктора, которые создают анонимный подкласс. Таким образом, Орика может узнать фактический параметр типа MyGenericClass<GenericParam1, GenericParam2>, используя ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments().

person Adam Michalik    schedule 17.02.2016
comment
Спасибо, это имеет смысл, создавать подклассы, чтобы узнать аргументы типа. Часто задаваемые вопросы по Orika могли бы указать на упомянутые вами модульные тесты. - person David Fernandez; 18.02.2016

Вы можете использовать TypeBuilder API для сохранения информации об универсальном типе, чтобы Orika могла использовать ее при выполнении сопоставления.

Обратите внимание, что Java не позволяет нам указывать параметр типа в Class литералах. Например, мы не можем написать Asset<Book>.class. Кроме того, из-за стирания типа мы не можем получить доступ к фактическому параметру типа во время выполнения. Короче говоря, необработанные типы, то есть Asset.class, не предоставляют Орике достаточно информации.

Итак, во-первых, мы должны создать общие типы, используя TypeBuilder:

Type<Asset<Person>> sourceType = new TypeBuilder<Asset<Person>>() {}.build();
Type<AssetDto<Person>> targetType = new TypeBuilder<AssetDto<Person>>(){}.build();

Затем в вызове classMap мы должны использовать эти типы:

factory.classMap(sourceType, targetType).byDefault().register();

Наконец, мы можем выполнить сопоставление, используя следующие типы:

factory.getMapperFacade().map(asset, sourceType, targetType);

Прочтите следующий пост для подробного объяснения использования универсальных шаблонов с Orika.

person isaolmez    schedule 29.05.2020