java中的自定义泛型
1.java中可以在方法中使用泛型,也可以在类中使用,如下:
//泛型必须先定义再使用
//在方法中使用泛型
public <T> void aa(T t){
}
2.如果一个类中多个方法使用同一个泛型,可以将其声明为泛型类,如下:
public class Demo1<T> {
//泛型必须先定义再使用
public <T> void aa(T t){
}
public void bb(T t){
}
//类上声明的泛型,只对非静态成员有效,所以在静态方法中需要自己声明泛型
public static <T> void cc(T t){
}
}
使用泛型Dao操作的场景———>>>>>
这里以hibernate举例
写一个使用hibernate操作数据库的基础Dao
public class BaseDao<T> {
private Session session;
private Class cla;
public BaseDao(Class cla){
this.cla=cla;
}
public void add(T t){
session.save(t);
}
public T find(String id){
return (T) session.get(cla, id);
}
public void update(T t){
session.update(t);
}
public void delete(String id){
T t=(T) session.get(cla, id);
session.delete(t);
}
}
操作Book的Dao
public class BookDao extends BaseDao<Book> {
public BookDao() {
super(Book.class);
}
}
业务操作(这里只是大致举例)
public class Demo {
public static void main(String[] args) {
// TODO Auto-generated method stub
BookDao dao=new BookDao();
dao.add(new Book());
}
}
但是这里有一个不太优雅的地方,我们每次在新建Dao继承基础Dao时
都需要调用父类构造函数,因为我们的BaseDao中没有写无参数构造函数
但是子类又需要使用父类的构造函数来实例化,所以这里必须显式调用一下
,并把Class(操作的数据实体)传过去—>
public class BookDao extends BaseDao<Book> {
public BookDao() {
super(Book.class);
}
}
要想解决这个问题,就不能在子类中这样传递Class了,那么为了得到实体类的Class,
我们需要这样改写BaseDao的构造函数:
public BaseDao(){
/*这里获取的是子类的Class
* 因为子类默认继承父类无参数构造方法,在调用时
* 相当于其子类使用了无参数构造方法,“this”就是
* 调用这个构造函数的那个子类
*/
Class cla=this.getClass();
//得到子类的父类,也就是BaseDao<Book>,这是一个泛型类型ParameterizedType
ParameterizedType pt=(ParameterizedType) cla.getGenericSuperclass();
/*得到参数化类型中的实际参数,因为参数可能有多个,比如:A<Book,User>
* 所以这里的方法是得到一个参数数组,我们得到其中的第一个(只有一个):Book
*/
cla= (Class) pt.getActualTypeArguments()[0];
this.cla=cla;
//打印看效果
System.out.println(cla);
}
上面构造器使用的这个技术叫做反射泛型