Аннотация для предоставления доступа доступным универсальный тип

Учитывая универсальный интерфейс как

interface DomainObjectDAO
{
   T newInstance();
   add(T t);
   remove(T t);
   T findById(int id);
   // etc...    
}

Я хотел бы создать подынтерфейс, который указывает параметр типа:

  interface CustomerDAO extends DomainObjectDAO 
  {
       // customer-specific queries - incidental.
  }

Реализация должна знать фактический шаблонный тип параметра, но конечно ввести средства стирания, не доступно во времени выполнения. Есть ли некоторая аннотация, которую я мог включать для объявления интерфейсного типа? Что-то как

  @GenericParameter(Customer.class)
  interface CustomerDAO extends DomainObjectDAO 
  {
  }

Реализация могла затем выбрать эту аннотацию от интерфейса и использовать его вместо универсального доступа типа во время выполнения.

Некоторый фон:

Этот интерфейс реализован с помощью JDK динамические прокси, как обрисовано в общих чертах здесь. Неуниверсальная версия этого интерфейса работала хорошо, но было бы более хорошо использовать дженерики и не иметь для создания методов в подынтерфейсе только для определения типа объекта области. Дженерики и прокси заботятся о большинстве вещей, но фактический тип необходим во времени выполнения для реализации newInstance метод, среди других.

11
задан mdma 15 June 2010 в 00:31
поделиться

2 ответа

Можно найти фактический аргумент типа подинтерфейса Dao (CustomerDAO), вызвав следующий метод:

import java.lang.reflect.ParameterizedType;

public static Class<?> getDomainClass(final Class<?> daoInterface) {
    ParameterizedType type = (ParameterizedType) daoInterface.getGenericInterfaces()[0];
    return (Class<?>) type.getActualTypeArguments()[0];
}

Когда вы вызываете его как

Class<?> domainClass = getDomainClass(daoInterface);

с daoInterface == CustomerDAO. class, то вы получите domainClass == Customer.class.

В моей реализации DaoFactory выполняет этот вызов и использует domainClass в качестве аргумента конструктора для DaoInvocationHandler.

7
ответ дан 3 December 2019 в 10:43
поделиться

Реализация должна знать фактический тип параметра шаблона.

Конечно, любая реализация CustomerDao неявно знает, что тип параметра - Customer. Он реализует DomainObjectDAO, а не DomainObjectDAO.

Проблемы возникнут только в том случае, если класс CustomerDao будет расширять общий абстрактный класс, и этому общему абстрактному классу понадобится знать фактический тип T. Но с этим можно справиться, передав объект Class для T (в данном случае Customer.class) суперклассу в качестве аргумента конструктора.

1
ответ дан 3 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: