反射

泛型的反射 案例,设置通用方法,会用到反射泛型!

步骤: 1. 案例分析 / 实现 2. 涉及知识点(jdk api) 3. 优化 / 反射泛型

反射泛型涉及API: Student 类型的表示 Id name ParameterizedType 参数化类型的表示 ArrayList<String>();

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

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

反射泛型案例 public class AdminDao extends BaseDao<Admin> {} public class AccountDao extends BaseDao<Account> {}

/**

  • 所有dao的公用的方法,都在这里实现
  • @author Jie.Yuan

*/ public class BaseDao<T>{

// 保存当前运行类的参数化类型中的实际的类型
private Class clazz;
// 表名
private String tableName;



// 构造函数: 1. 获取当前运行类的参数化类型; 2. 获取参数化类型中实际类型的定义(class)
public BaseDao(){
	//  this  表示当前运行类  (AccountDao/AdminDao)
	//  this.getClass()  当前运行类的字节码(AccountDao.class/AdminDao.class)
	//  this.getClass().getGenericSuperclass();  当前运行类的父类,即为BaseDao<Account>
	//                                           其实就是“参数化类型”, ParameterizedType   
	Type type = this.getClass().getGenericSuperclass();
	// 强制转换为“参数化类型”  【BaseDao<Account>】
	ParameterizedType pt = (ParameterizedType) type;
	// 获取参数化类型中,实际类型的定义  【new Type[]{Account.class}】
	Type types[] =  pt.getActualTypeArguments();
	// 获取数据的第一个元素:Accout.class
	clazz = (Class) types[0];
	// 表名  (与类名一样,只要获取类名就可以)
	tableName = clazz.getSimpleName();
}


/**
 * 主键查询
 * @param id	主键值
 * @return      返回封装后的对象
 */
public T findById(int id){
	/*
	 * 1. 知道封装的对象的类型
	 * 2. 表名【表名与对象名称一样, 且主键都为id】
	 * 
	 * 即,
	 * 	  ---》得到当前运行类继承的父类  BaseDao<Account>
	 *   ----》 得到Account.class
	 */
	
	String sql = "select * from " + tableName + " where id=? ";
	try {
		return JdbcUtils.getQuerrRunner().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.getQuerrRunner().query(sql, new BeanListHandler<T>(clazz));
	} catch (SQLException e) {
		throw new RuntimeException(e);
	}
}

}

  1. 反射复习 反射,可以在运行时期动态创建对象;获取对象的属性、方法;

public class Admin {

// Field
private int id = 1000;
private String name = "匿名";

// Constructor
public Admin(){
	System.out.println("Admin.Admin()");
}
public Admin(String name){
	System.out.println("Admin.Admin()" + name);
}

// Method
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 class App {

// 1. 创建对象
@Test
public void testInfo() throws Exception {
	// 类全名
	String className = "cn.andday.c_reflect.Admin";
	// 得到类字节码
	Class<?> clazz = Class.forName(className);
	
	// 创建对象1: 默认构造函数简写
	//Admin admin = (Admin) clazz.newInstance();
	
	// 创建对象2: 通过带参数构造器创建对象
	Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
	Admin admin = (Admin) constructor.newInstance("Jack");
	
}
@Test
//2. 获取属性名称、值
public void testField() throws Exception {
	
	// 类全名
	String className = "cn.andday.c_reflect.Admin";
	// 得到类字节码
	Class<?> clazz = Class.forName(className);
	// 对象
	Admin admin =  (Admin) clazz.newInstance();
	
	// 获取所有的属性名称
	Field[]  fs =  clazz.getDeclaredFields();
	// 遍历:输出每一个属性名称、值
	for (Field f : fs) {
		// 设置强制访问
		f.setAccessible(true);
		// 名称
		String name = f.getName();
		// 值
		Object value = f.get(admin);
		
		System.out.println(name + value);
	}
}

@Test
//3. 反射获取方法
public void testMethod() throws Exception {
	
	// 类全名
	String className = "cn.andday.c_reflect.Admin";
	// 得到类字节码
	Class<?> clazz = Class.forName(className);
	// 对象
	Admin admin =  (Admin) clazz.newInstance();
	
	// 获取方法对象    public int getId() {
	Method m = clazz.getDeclaredMethod("getId");
	// 调用方法
	Object r_value = m.invoke(admin);
	
	System.out.println(r_value);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值