Genericdao - Is that correct?

Asked

Viewed 545 times

6

I’m implementing a simple GenericDAO as below, but I feel like I’m doing the wrong thing, it works but I feel like there’s something wrong anyway, could help me?

I created an interface like this:

public interface GenericDAO<T, ID> {
    public List<T> listaTodos(Class<T> clazz);
    public List<T> listaComLimite(Class<T> clazz, Integer limite);
    public T porId(Class<T> clazz, ID id);
    public void adiciona(T t);
    public T grava(T t);
    public void remove(Class<T> clazz, ID id);
}

Then I created another interface (more specific), that is with what is not generic, but as we can see this extends of GenericDAO previous:

public interface TestDAO extends GenericDAO<Test, Long> {
    public Test buscaPorNome(String nome);
}

Below I’m testing how would use:

public void getTest(){
    Test teste = testDAO.porId(Test.class, id);
}

It sounds silly, but when I extended the GenericDAO I’ve passed the target class:

extends GenericDAO<Test, Long>

The question is, because when I’m gonna use it I need to go through it again, like this?

Test teste = testDAO.porId(Test.class, id);

It doesn’t seem wrong?

1 answer

7

There is nothing wrong with your code. Many frameworks use that approach with parameters of the type Class<T> to circumvent the limitations of the Java generic implementation (in short the problem is that <T> is "deleted" at runtime).

That said, there is a workaround known for this type of situation. If your classes extend a generic base class you can extract this generic type from the superclass through reflection.

For example, if you have a class GenericDaoImpl<T> and a specific subclass SpecificDaoImpl extends GenericDaoImpl<Specific>):

private final Class<T> minhaClasse; 

public GenericDaoImpl() {
    minhaClasse = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
            .getActualTypeArguments()[0];

}

The advantage here is that you don’t need to pass the kind of class ever.

Alternatively, to avoid having to deal with reflection, you can also use the generic class constructor to receive the type (and specify the type as argument in the constructor of the specific class only once):

private final Class<T> minhaClasse;

public GenericDaoImpl(Class<T> minhaClasse) {
    this.minhaClasse = minhaClasse;
}

// E na classe específica
public SpecificDaoImpl() {
    super(TipoDaMinhaClasseEspecífica);
}

I can’t tell you which implementation would be "more correct". It is worth using what is most practical in your case.


Source: Soen - Get Generic type of class at Runtime.

  • Digging through the comments on Soen I found the library Typetools capable of solving the types "raw".

  • Hello Anthony, Your answer was perfect, I did the test by the constructor and really got less repetitive work. Thank you so much!!! I hope one day to get good in JAVA and OO to help tb... Abs. Marcelo

  • Hi Marcelo. I’m glad to have helped.I’m sure you will still contribute to the community. If the answer solved your problem don’t forget to accept it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.