1. 反射泛型信息
abstract class A<T> {
// 无参构造器
public A(){
// 在这里获取子类传递的泛型信息, 要得到一个 Class!
Class clazz = this.getClass(); // 得到子类的类型
// 获取传递给父类参数化类型
Type type = clazz.getGenericSuperclass();
// 将 Type 类型转换为 ParameterizedType
// 它就是对应的 A<String> 或 A<Integer>
ParameterizedType pType = (ParameterizedType)type;
// 获取泛型信息, 它是一个 Class 数组
Type[] types = pType.getActualTypeArguments();
Class c = (Class)types[0]; // 它就是 String 或 Integer
}
}
class B extends A<String>{
}
class C extends A<Integer>{
}
2. 反射注解
2.1 要求
- 注解的保留策略必须是
RUNTIME
2.2 反射注解需要从作用目标上返回
- 类上的注解,需要使用
Class
来获取; - 方法上的注解, 需要使用
Method
来获取; - 构造器上的注解,需要使用
Constructor
来获取; - 成员上的注解,需要使用
Field
来获取. - 其中
Method, Constructor, Field
有共同的父类AccessibleObject
.
// 反射注解
public class Demo{
// 获取 A 类上的 MyAnno2 注解
public void fun(){
// 1. 得到作用目标
Class<A> c = A.class;
// 2. 获取指定类型的注解
// 该注解的保留策略必须是 RUNTIME
MyAnno2 myAnno2 = c.getAnnotation(MyAnno2.class);
System.out.println(myAnno2.name()+","+myAnno2.age()+","+myAnno2.sex());
}
// 获取 fun1 方法上的 MyAnno2 注解
public void fun2(){
// 1. 得到作用目标
Class<A> c = A.class;
Method method = c.getMethod("fun1");
// 2. 获取指定类型的注解
MyAnno2 myAnno2 = method.getAnnotation(MyAnno2.class);
}
}
@MyAnno2(name="A类",age=23,sex="男")
@MyAnno3(age=25)
class A {
@MyAnno2(name="fun1方法",age=24,sex="女")
public void fun1(){
...
}
}
// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno2 {
String name();
int age();
String sex();
}
@interface MyAnno3{
int age();
}
3. 反射泛型和注解的应用(初级Hibernate)
// BaseDao 将 dbUtils 升级
public class Demo{
private QueryRunner qr = new TxQueryRunner();
// 添加用户
public void addUser(User user){
String sql = "";
Object[] params = { };
qr.update(sql,params);
}
// 添加分类
public void addCategory(Category category){
String sql = "";
Object[] params = { };
qr.update(sql,params);
}
}
class BaseDAO<T> {
private QueryRunner qr = new TxQueryRunner();
private Class<T> beanClass;
// 无参构造方法
public BaseDAO(){
// 获取泛型的值,进而查询出表名
beanClass = (Class)((ParameterizedType)this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
/*
*
* public void add(T bean){
*
* String sql = "insert into 表名 values(几个?)";
* Object[] params = {参数值是什么};
* qr.update(sql,params);
* }
*/
public void add(T bean){
// 获取 T 类型中成员个数, 确定 values(参数个数)
Field[] fs = beanClass.getDeclaredFields();
// 如果规定表名和类名相同
// 拼凑 sql 语句
String sql = "insert into "+beanClass.getSimpleName()+" values (";
for(int i=0; i< fs.length; i++){
sql += "?";
if(i < fs.length - 1){
sql += ",";
}
}
sql += ")";
}
public void update(T bean){
}
public void delete(String uuid){
}
public T load(String uuid){
return null;
}
public List<T> findALl(){
return null;
}
}
class UserDAO extends BaseDAO<User>{
public void addUser(User user){
super.add(user);
}
}
参考资料: