GenericDAO - Is that correct?

5

I'm implementing a simple GenericDAO as below, but I feel like I'm doing something wrong, it works but I feel like there's something wrong anyway, could you 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 how can we see this extends of GenericDAO previous:

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

Below I'm testing how it would look:

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

It sounds like bullshit, but when I've extended GenericDAO I've already passed the target class:

extends GenericDAO<Test, Long>

The question is, why should I use it again when I'm going to use it?

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

Does not that sound wrong?

    
asked by anonymous 05.01.2015 / 15:57

1 answer

7

There's nothing wrong with your code. Many frameworks use this approach with parameters of type Class<T> to bypass the limitations of Java's generic implementation (in short, the problem is that <T> is " / p>

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 do not need to pass the class type ever.

Alternatively, to not have to deal with reflection, you can also use the constructor of the generic class 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 not tell you which implementation would be "most correct." It pays to use whatever is most practical in your case.

Source: SOen - Get generic type of class at runtime a>.

    
05.01.2015 / 16:26