Как связать общий класс?

Когда я пытаюсь издеваться над Дао, используя Jukito, я получаю следующее исключение:

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at org.jukito.JukitoModule.addKeyDependency(JukitoModule.java:338)
    at org.jukito.JukitoModule.addInjectionPointDependencies(JukitoModule.java:330)
    at org.jukito.JukitoModule.addDependencies(JukitoModule.java:313)

Объект, который я пытаюсь высмеять, это ConcreteDao,

public class ConcreteDao extends AbstractDao<MyDomain> {
}

public abstract class AbstractDao<T extends DatastoreObject> {
}

Я прочитал несколько постов на SO об этом обобщении дженериков, но я не могу найти способ использовать TypeLiteral для моего связывания.

Вот что я попробовал:

bind(new TypeLiteral<AbstractDao<MyDomain>>(){}).to(ConcreteDao.class);

1 ответ

Вам нужно связать так:

bind(new TypeLiteral<AbstractDao<MyDomain>>(){}).to(new TypeLiteral<ConcreteDao<MyDomain>>(){});

Вот как вы можете получить универсальный класс:

class AbstractDao {
  protected final Class<T> clazz;

  @Inject
  public AbstractDao(TypeLiteral<T> type) {
    clazz = (Class<T>) type.getRawType();
  }
}

Подклассы AbstractDao нужно будет передать конкретный объект TypeLiteralс родительского класса (AbstractDao):

class ConcreteDao extends AbstractDao<MyDomain> {
  @Inject
  public ConcreteDao(TypeLiteral<MyDomain> type) {
    super(type);
  }
}

Обратите внимание, что вы можете сделать свой класс AbstractDao неабстрактным и реализовать базовые операции CRUD, чтобы вы могли использовать его без необходимости расширять AbstractDao для каждой сущности. Вам просто понадобится привязка для каждой сущности, например:

bind(new TypeLiteral<GenericDao<User>>(){}).in(Scopes.SINGLETON);

Смотрите мой блог для получения дополнительной информации.

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