Aşağıda herhangi bir T tipinde sınıf için çalışan ve kendisine nesne eklenmesini ve alınmasını sağlayan örnek
public class GenericTest<T> {
private Object[] objects=new Object[10];
public void add(int i,T o){
objects[i]=o;
}
public T get(int i){
return (T)objects[i];
}
}
Sınıf GenericTest
GenericTest<String> gtS=new GenericTest<String>(); GenericTest<Integer> gtInt=new GenericTest<Integer>(); GenericTest<Date> gtDate=new GenericTest<Date>(); gtS.add(1,"Test 1"); gtInt.add(1,1); gtDate.add(1,new Date());
Görüldüğü gibi bir nesne new GenericTest<string>() şeklinde yaratılırsa ona ancak String tipinde veri eklenebilir
public class GenericTest<T extends GenericBaseTest> {
...
}
Yukarıdaki GenericTest sınıfı sadece GenericBaseTest sınıfından türetmiş sınıflar için çalışacaktır. GenericBaseTestExt sınıfı GenericBaseTest sınıfından türemişse aşağıdaki gibi bir kod yazılabilir : GenericTest<GenericBaseTestExt> gt=new GenericTest<GenericBaseTestExt>();
public class GenericTest<T extends GenericBaseTest> {
...
}
Yukarıdaki GenericTest sınıfı sadece GenericBaseTest sınıfından türetmiş sınıflar için çalışacaktır. GenericBaseTestExt sınıfı GenericBaseTest sınıfından türemişse aşağıdaki gibi bir kod yazılabilir :GenericTest<GenericBaseTestExt> gt=new GenericTest<GenericBaseTestExt>(); GenericTest<? extends GenericBaseTest> gtGeneral=gt;Yukarıdaki örnekde gtGeneral nesnesi GenericBaseTest sınıfından türüyen herhangi bir sınıfla çalışabileceği anlamına gelmektedir.
GenericTest<GenericBaseTestExt> gt=new GenericTest<GenericBaseTestExt>(); GenericBox<? super GenericBaseTestExt2> gtSuper=gt;
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 kurucudaParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); entityClass = (Class<T>) genericSuperclass.getActualTypeArguments()[0];