泛型的反射
泛型的反射
需求:
设置通用方法,会用到泛型的反射技术!
反射泛型涉知识及API:
例如:
Student对象 类型的表示
ParameterizedType 参数化类型的表示
Type接口 Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
List<String>list = newArrayList<String>();
泛型集合: list
集合元素定义:newArrayList<String>(); 中的String
参数化类型ParameterizedType :即:“ArrayList<String> ” 为参数化类型
案例:
2张表(Account/Users)同时需要“通过主键id”获取数据。
表Users对应的实体类对象
package com.cn.reflect;
public class Users {
private int id;
private String name;
private String password;
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "Users [id=" + id + ", name=" + name + ", password=" + password
+ "]";
}
}
表Account对应的实体类对象
package com.cn.reflect;
public class Account {
private int id;
private String accountName;
private double money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", accountName=" + accountName
+ ", money=" + money + "]";
}
}
2张表dao的父类BaseDao写公共的方法
package com.cn.reflect;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.cn.Util.JdbcUtils;
/**
* 该类写公共的通用方法
* @author liuzhiyong
*
*/
public class BaseDao<T> {
//保存当前运行类的参数化类型中的实际类型
private Class clazz;
//保存当前对象对应的 表名
private String tableName;
//构造函数:1.获取当前运行类的参数化类型;2.获取参数化类型中的实际类型的定义(class)
public BaseDao(){
// this 表示当前运行类(AccountDao/UsersDao)
Class<? extends BaseDao> clazz1 = this.getClass();//获取当前运行类的字节码(AccountDao/UsersDao)
//获取当前运行类的父类,即为BaseDao<AccountDao/UsersDao>,其实就是“参数化类型“,ParameterizedType
Type type = clazz1.getGenericSuperclass();
//强转为“参数化类型”
ParameterizedType pt = (ParameterizedType)type;
Type[] types = pt.getActualTypeArguments();//返回表示此类型实际类型参数的 Type对象的数组。AccountDao.class/UsersDao.class
//获取实际类型参数的Type对象的第一个元素:AccountDao.class/UsersDao.class
clazz = (Class)types[0];
//表名(与类名一样,只要获取类名就可以)
tableName = clazz.getSimpleName();
}
/**
* 根据表主键查询
* @param id 主键值
* @return 返回封装后的对象
*/
public T findById(int id){
/**
* 1.知道了封装的对象的类型
* 2.知道了表名
*/
String sql = "select * from " + tableName + " where id = ?";
try {
return JdbcUtils.getQueryRunner().query(sql, new BeanHandler<T>(clazz), id);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* 获取表所有数据
* @return
*/
public List<T> getAll(){
String sql = "select * from " + tableName;
try {
return JdbcUtils.getQueryRunner().query(sql, new BeanListHandler<T>(clazz));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
UsersDao继承BaseDao
package com.cn.reflect;
/**
* 基于分层的必要性,这个方法不可少,这里写父类没有实现的方法(个性化需求)
* @author liuzhiyong
*
*/
public class UsersDao extends BaseDao<Users> {
}
AccountDao继承BaseDao
package com.cn.reflect;
/**
* 基于分层的必要性,这个方法不可少,这里写父类没有实现的方法(个性化需求)
* @author liuzhiyong
*
*/
public class AccountDao extends BaseDao<Account> {
}
测试类
package com.cn.reflect;
import java.util.List;
import org.junit.Test;
public class Demo1 {
@Test
public void test() throws Exception {
AccountDao accountDao = new AccountDao();
Account account = accountDao.findById(1);
System.out.println(account);
List<Account> accountList = accountDao.getAll();
System.out.println(accountList.toString());
UsersDao usersDao = new UsersDao();
Users users = usersDao.findById(1);
System.out.println(users);
List<Users> usersList = usersDao.getAll();
System.out.println(usersList.toString());
}
}