java泛型反射总结

来源:互联网 发布:网络教学有什么特点 编辑:程序博客网 时间:2024/06/03 19:12

引入:

      在需求中,数据库有两张表user,admin。我们要查询里面的id,name等信息通常都是写两个dao,然后分别给每个查询字段写一套方法。

     然而其实查询这些字段的方法都大同小异,所以产生了一个更好的解决办法,就是写一个通用的dao,然后把相同的方法写在通用的dao(genericDao)里,然后然实体dao去继     承它。

   

    下面通过模拟 贴出一般做法 和 优化后的做法:

    首先 在数据库里建好两张表,分别为user和admin,再插入一些数据

   

CREATE TABLE USER(id INT PRIMARY KEY,userName VARCHAR(20),age INT);CREATE TABLE admin(id INT PRIMARY KEY,adminName VARCHAR(20),status_ INT);INSERT INTO USER VALUES(1,'李四',21);INSERT INTO USER VALUES(2,'张三',20);INSERT INTO admin VALUES(1,'超级管理员',1);INSERT INTO admin VALUES(2,'普通管理员',0);
        截下来写两个实体类

public class admin {private int id;private String adminName;private int status_;public admin() {super();// TODO Auto-generated constructor stub}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getAdminName() {return adminName;}public void setAdminName(String adminName) {this.adminName = adminName;}public int getStatus_() {return status_;}public void setStatus_(int status_) {this.status_ = status_;}@Overridepublic String toString() {return "admin [id=" + id + ", adminName=" + adminName + ", status_=" + status_ + "]";}}

public class user {private int id;private String userName;private int age;public user() {super();// TODO Auto-generated constructor stub}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "userDao [id=" + id + ", userName=" + userName + ", age=" + age + "]";}}

一般做法

   
public class adminDao{public admin getById(int id){QueryRunner qr=jdbcUtil.getQueryRunner();try {return (admin)qr.query("select * from admin where id=", new BeanHandler(admin.class),new Object[]{id});} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException(e);}}@Testpublic void testId(){adminDao adminDao = new adminDao();admin byId = adminDao.getById(2);System.out.println(byId);}}

public class userDao extends genericDao<user>{public user getById(int id){QueryRunner qr=jdbcUtil.getQueryRunner();try {return (user)qr.query("select * from user where id=?", new BeanHandler(user.class),new Object[]{id});} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException(e);}}@Testpublic void testId(){userDao userDao = new userDao();user byId = userDao.getById(2);System.out.println(byId);}}

利用泛型优化后的做法:

    首先写一个genericDao
  
** * 通用的dao方法 * @author Administrator * */public class genericDao <T>{private Class clazz;private String tableName;public genericDao(Class clazz,String tableName){this.clazz=clazz;this.tableName=tableName;}public  T getById(int id){QueryRunner qr=jdbcUtil.getQueryRunner();try {return (T)qr.query("select * from "+tableName+" where id=?", new BeanHandler(clazz),new Object[]{id});} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException(e);}}}
然后让实体Dao类分别继承它
public class adminDao extends genericDao<admin>{public adminDao() {super(admin.class, "admin");}@Testpublic void testId(){adminDao adminDao = new adminDao();admin byId = adminDao.getById(2);System.out.println(byId);}}

public class userDao extends genericDao<user>{public userDao() {super(user.class, "user");}@Testpublic void testId(){userDao userDao = new userDao();user byId = userDao.getById(2);System.out.println(byId);}}



利用泛型反射技术优化后的做法


generic类
/** * 通用的dao方法 * @author Administrator * */public class genericDao <T>{private Class clazz;private String tableName;public genericDao(){System.out.println(this);//this 指当前运行的类对象  如果有子类继承它,则它指的是子类,而不是generic本身类System.out.println(this.getClass());//获得当前运行类的字节码System.out.println(this.getClass().getSimpleName());//获得当前运行类的类名System.out.println(this.getClass().getSuperclass());//获得当前运行类的父类的字节码System.out.println(this.getClass().getGenericSuperclass());//获得参数化类型  reflect.genericDao<reflect.admin>/** * 参数化类型:genericDao<reflect.admin> * 实体类型:reflect.admin *///1.先获得当前运行类的泛型父类类型Type type = this.getClass().getGenericSuperclass();//2.强转为参数化类型ParameterizedType p=(ParameterizedType)type;//3.获取参数化类型中,实际类型的定义Type[] actualTypeArguments = p.getActualTypeArguments();//获取数组的第一个元素,即我们想要的实际类型的字节码类型clazz=(Class<T>) actualTypeArguments[0];//给表名赋值tableName=clazz.getSimpleName();}public  T getById(int id){QueryRunner qr=jdbcUtil.getQueryRunner();try {return (T)qr.query("select * from "+tableName+" where id=?", new BeanHandler(clazz),new Object[]{id});} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException(e);}}}

 简化后的dao类
public class userDao extends genericDao<user>{@Testpublic void testId(){userDao userDao = new userDao();user byId = userDao.getById(2);System.out.println(byId);}}
public class adminDao extends genericDao<admin>{@Testpublic void testId(){adminDao adminDao = new adminDao();admin byId = adminDao.getById(2);System.out.println(byId);}}


得出结论:子类继承父类,并传一个实际类型给父类,父类可以在类中通过反射技术先获得参数化类型,再获得参数化类型中的实际类型。即xxx.class

     

0 0