泛型的反射

前言:

设置通用方法,会用到反射泛型。

先来认识一下Type这个接口:

Type 接口,任何类型默认的接口!
包括: 引用类型、原始类型、参数化类型

List<String>  list   =  new   ArrayList<String>();
泛型集合:    list
集合元素定义:new   ArrayList<String>();  中的String
参数化类型:  ParameterizedType 
即:“ArrayList<String> ” 为参数化类型

参数化类型是Type接口的一个实现接口

接下来的栗子就是用到了 :参数化类型。

了解下 我们以前在写dao层的时候其实都是重复代码,比如

根据教师的id,学生的id查找教师和学生的信息
查找教师的全部信息,查找学生的全部信息

在这里面,只有类不一样,其他的代码是完全冗余的,我们需要抽离出来,写一个通用类。这里就用到了参数化类型。

students类:

public class students {
    private int id;
    private String name;
    private int age;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
@Override
public String toString() {
    // TODO Auto-generated method stub
    return id+":"+name+":"+age;
}
}

users类:

public class users {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return id + ":" + name;
    }
}

注意:实体类和数据库的表类相同,方便操作
子类dao层:users类

public class UserDao extends BasicDao<users>{

}

子类dao层:students类

public class StudentDao extends BasicDao<students>{

}

只要在BasicDao父类中实现通用方法即可。
这里父类就用到了泛型来接收子类传递过来的参数,然后使用参数化类型中提取出运行类的类型。

public class BasicDao<T> {
    // 保存当前运行类的参数化类型中的实际的类型
    private Class actualClass;
    private String table;
    //  构造函数: 
    // 1. 获取当前运行类的参数化类型;  
    // 2. 获取参数化类型中实际类型的定义(class)
    public BasicDao() {
        //getGenericSuperclass
        //当前运行类(UserDao类)的超类,即为BaseDao<Account>
        Type type= this.getClass().getGenericSuperclass();
        //其实就是参数化类型   所以强制转换为“参数化类型”
        ParameterizedType parameterizedType = (ParameterizedType) type;
        //获取全部的参数化类型,本次中只有users或者students
        Type[] types = parameterizedType.getActualTypeArguments();
        actualClass = (Class) types[0];
        //获取实际类的名字 去掉路径
        table = actualClass.getSimpleName();
    }
    public T findById(int id) throws SQLException {
        String sql = "SELECT * FROM "+table+" where id = ?";
        return JdbcUtilsC3p0.getQueryRunner().query(sql, new BeanHandler<T>(actualClass), id);
    }
    public List<T> findAll() throws SQLException{
        String sql = "SELECT * FROM "+table;
        return JdbcUtilsC3p0.getQueryRunner().query(sql, new BeanListHandler<T>(actualClass));
    }
}

运行入口:

public class Main {
    public static void main(String[] args) throws SQLException {
        UserDao userDao = new UserDao();
        StudentDao studentDao = new StudentDao();

        users user = userDao.findById(1);
        List<users> usersOne = userDao.findAll();
        students student = studentDao.findById(1);
        List<students> studentsOne = studentDao.findAll();
        System.out.println(user);
        System.out.println(usersOne);
        System.out.println(student);
        System.out.println(studentsOne);
    }
}

输出:

1:我
[1:我, 2:是, 3:你]
1:我:12
[1:我:12, 2:你:33]

注意下:
我这里还用到了 C3p0

public class JdbcUtilsC3p0 {

    //创建数据源
    private static DataSource dataSource;
    static {
        dataSource = new ComboPooledDataSource();
    }

    //获取dbutils操作的核心方法
    public static QueryRunner getQueryRunner() {

        return new QueryRunner(dataSource);
    }
}
<c3p0-config>
 <default-config>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/daynow?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false</property>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="initialPoolSize">3</property>
        <property name="maxPoolSize">6</property>
        <property name="maxIdleTime">1000</property>
    </default-config>
</c3p0-config>

猜你喜欢

转载自blog.csdn.net/qq_38409944/article/details/81485108