Generic bir sınıf yaptığınızda , generic verilen parametrenin sınıfına ihtiyacınız olabilir. Normal durumda metot içinde verilen parametrenin sınıfını bulamazsınız. Örneğin JPA için genel bir data access sınıfı aşağıdaki gibi olsun :
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
public class GenericDao<T,PK> {
private EntityManager entityManager;
public GenericDao() {
entityManager = Persistence.createEntityManagerFactory("TestJPA").createEntityManager();
}
public Test find(Long id) {
return entityManager.find(entityClass, id); // hata
}
public void create(Test t) {
entityManager.persist(t);
}
public void update(Test t) {
entityManager.merge(t);
}
public void delete(Test t) {
entityManager.remove(t);
}
}
Yukarıdaki kod derlenemez. entityManager.find(entityClass, id) satırında T'nin sınıfı gerekmektedir. Generic bir değişkenin sınıfını o anda alamazsınız. T'nin sınıfını almak için T sınıfı için kurucuda bir Class değişkeni yaratılabilir ve aşağıdaki gibi yaratılabilir :
import java.lang.reflect.ParameterizedType;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
public class GenericDao<T, PK> {
private EntityManager entityManager;
protected Class<T> entityClass;
public GenericDao() {
entityManager = Persistence.createEntityManagerFactory("TestJPA").createEntityManager();
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
}
public T find(Long id) {
return entityManager.find(entityClass, id); // hata
}
public void create(T t) {
entityManager.persist(t);
}
public void update(T t) {
entityManager.merge(t);
}
public void delete(T t) {
entityManager.remove(t);
}
}
Görüldüğü gibi kurucuda
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];
ile T argümanın sınıfı tespit edilmiştir. Bu şekilde find metodunda kullanılabilir.