反射
主流框架中大量应用了反射技术
主要目的
对类的结构进行解析,实现代码的解耦
硬编码
Student stu = new Student(1,"张三",20); stu.study();
反射机制对类的结构进行解析,读取类中的方法和属性,可以动态创建对象,可以实现方法的调用。
API
在java.refect包
Class 类的类型
Method 类的方法
Field 类的属性
Constructor 类的构造方法
反射的过程:
1)获得类的类型
2)获得类的方法或属性
3)创建类的对象
4)调用对象的方法或属性
获得类的类型
1)Class Class.forName("包名+类名")
2)Class 类名.class
3)Class 对象.getClass()
获得类的方法或属性
- Method[] getMethods()
获得类中所有方法(包含自己定义的方法和从父类继承的方法) - Method[] getDeclaredMethods()
获得类中所有方法(包含自己定义的方法) - Method getMethod(String name,Class<?>... paramTypes)
获得特定方法,name是方法名
paramTypes 是参数的类型 - Method getDeclaredMethod(String name,Class<?>... paramTypes)
获得自己定义的特定方法 - Field[] getFields()
获得类中所有属性(包含自己定义的和从父类继承的) - Field[] getDeclaredtFields()
获得类中所有属性(自己定义的) - Field getField(String name)
获得属性,name是属性名
paramTypes 是参数的类型 - Field getDeclaredField(String name)
获得自己定义的属性
创建类的对象
Object 类型对象.newInstance()
调用类型无参构造方法调用类有参的构造方法创建对象
1. 获得类的构造方法Constructor 类型对象.getDeclaredConstructor(Class<?>... paramTypes)
2. 通过构造方法创建对象Object Constructor对象.newInstance(参数...)
调用对象的方法或属性
- Method
Object invoke(Object obj,Object... params) 调用方法
返回值Object是方法的返回值类型
第一个参数Object是调用此方法的对象
Object... 调用此方法的实际参数
思考题:
如何结合JDBC和反射机制实现将查询数据转换为List集合
public class JdbcUtils2 { //查询多条数据 public static <T> List<T> queryList(Class clazz,String sql,Object... params){ //使用JDBC查询得到ResultSet //创建List集合 //循环遍历结果集,目的包装结果集的每一行数据到实体对象中 //使用反射创建实体对象(表的列名和属性名相同) //获得类中所有属性 //遍历到每个属性,用属性名到结果集中取数据 (getObject(列名)) //使用反射给属性赋值 //添加实体对象到集合 //返回集合 return null; } }
注解
JDK1.5开始支持
可以在类、方法、属性上面添加一些额外的数据,起到标识作用
常用注解:
@Test 方法,标识测试方法 @WebServlet("url") 类,标识类是Servlet @Override 方法,标识方法必须是重写父类的 @SuppressWarnings 抑制警告 @Depricated 标识属性或方法过时
自定义注解:
需要使用四个元注解(标识注解的注解) @Documented 注解信息是否包含在文档(非必须) @Inherited 是否被子类继承(非必须) @Retention 使用注解的时机 RetentionPolicy.Runtime 程序运行时 RetentionPolicy.Source 编码时 RetentionPolicy.Class 类加载时 @Target 使用注解的目标 ElementType.Type 用在类、接口、枚举上 ElementType.Method 用在方法上 ElementType.Field 用在属性上
语法:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Column { //列名 String columnName(); } @Column(columnName="列名") 类型 属性;
通过反射读取注解的内容
注解类型 column= 属性.getDeclaredAnnotation(注解的类型); String cname = column.columnName(); //获得配置的内容
作业:
1)使用反射+JDBC实现表的查询返回List集合 2)通过注解配置属性的列名 定义+使用+读取 3)思考:使用反射机制完成类似Gson的框架 实现将Json数组解析为List集合 class Person{ private String name; private int age; //set、get.... } String json = "[{\"name\":\"张三\",\"age\":\"20\"},{\"name\":\"李四\",\"age\":\"23\"}]"; 方法定义: public static <T> List<T> fromJson(Class clazz,String json){ .... }