反射:框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化代码;
概念
将类的各个组成部分封装为其他对象,这就是反射机制。
好处
- 可以在程序运行过程中操作这些对象。
- 可以解耦来提高程序的可扩展性。
获取Class对象的方式
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象,多用于配置文件,将类名定义在配置文件中。读取文件,加载类。
- 类名.class:通过类名的属性class获取,多用于参数的传递。
- 对象.getClass():getClass()方法在object类中定义着。多用于对象的获取字节码的方式。
结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
Class对象功能
获取功能:
- 获取成员变量:
- Field[] getFields():获取所有public修饰的成员变量。
- Field getField(String name)
- Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
- Field getDeclaredField(String name)
- 获取构造方法
- Constructor<?>[] getConstructors()
- Constructor
getConstructor(Class<?>… parameterTypes) - Constructor<?>[] getDeclaredConstructors()
- Constructor
getDeclaredConstructor(Class<?>… parameterTypes)
- 获取成员方法
- Method[] getMethods()
- Method getMethod(String name, Class<?>… parameterTypes)
- Method[] getDeclaredMethods()
- Method getDeclaredMethod(String name, Class<?>… parameterTypes)
- 获取类名
- String getName()
Filed:成员变量
操作:
- 设置值
- void set(Object obj, Object value)
- 获取值
- get(Boject obj)
- 忽略访问修饰符的安全检查
- void setAccessible(boolean flag);//设置权限,暴力反射
Constructor:构造方法
- 创建对象
- T newInstance(Object… initargs)
- 如果使用空参数构造方法创建对象,操作可以简化:class对象的newInstance方法。
Method:方法对象
- 执行方法
- Object invoke(Object obj, Object args)
- 获取方法名称
- String getName();
注解
概念
注解(Annotation),也叫元数据。一种代码级别的说明,他是JDK1.5之后的版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
格式:@注解名称
作用分类
- 编写文档:通过代码里标识的元数据生成文档(doc)
- 代码分析:通过代码里标识的元数据对代码进行分析(使用反射)
- 编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查(Override)
JDK预定义的一些注解
- @Override:检测被该注解标注的方法是否继承自父亲(接口)的
- @Deprecated:该注解标注的内容,表示已过时
- @SuppressWarnings:压制警告
自定义注解
- 格式:
- 元注解
- public @interface 注解名称{}
- 本质
- 本质上就是一个接口,该接口默认继承Annotation接口
- 属性:接口中的抽象方法
- 要求:属性的返回值类型有要求:基本数据类型、String、枚举、注解、以上数据类型的数组。
- 定义了属性,在使用时需要给属性赋值
- 如果定义属性时,使用default关键字给属性默认初始化值,在使用注解时,可以不进行属性的赋值
- 如果只有一个属性需要赋值,并且属性的名称为value,则value可以省略,直接定义值即可。
- 数组使用{},如果只有一个元素,可以省略
元注解
用于描述注解的注解
- @Target:描述注解能够作用的位置:ElementType.TYPE
- TYPE:作用于类上
- METHOD:可以作用与方法上
- FIELD:可以作用于成员变量上
- @Retention:描述代码被保留的阶段:ReteneionPolicy.RUNTIME
- RUNTIME:当前被描述的注解,会保留到class字节码文件中,并被JVM读取到。
- @Document:描述注解是否被抽取到API文档中
- Inherited:描述注解是否被子类继承