反射就是指以对象的方式操作原本类中的内容,将类中的成员变量、成员方法、构造方法分别封装成对象的形式,通过操作这些对象,达到操作类中内容的方法。
反射由于操作的是类的字节码对象,因此有着两点好处:第一是打破原本类中内容访问的局限性,主要就是可以访问被 private 修饰的成员变量、成员方法、构造方法。第二是通过配置文件 properties 的方法,降低程序的耦合,从而提升程序的扩展性和维护性。
反射有着三种不同的方式获取到类的字节码对象,分别对应着Java程序运行的三个阶段分别是源文件阶段,使用 Class.forName(“全类名”) 的方式获取到该类的字节码对象;第二阶段是生成 Class 类对象阶段,通过使用 类名.class 的方式,获取到字节码对象;第三阶段是创建对象(运行)阶段,通过使用 对象名.class 的方式,获取到字节码对象。
通过这三种方式获取到字节码对象之后,通过 Constructor对象,Field对象,Method对象就可以获取到类中的构造方法、成员变量、成员方法,进而就可以操作构造方法进行创建对象和初始化成员变量,操作成员变量进行对其进行赋值,操作成员方法进行方法的调用。
在反射中,有一个很重要的功能就是暴力反射机制,通过调用 setAccessible(true)方法,获取到被私有修饰的成员变量、成员方法、构造方法的访问权限,因此在反射机制下,没有不可以访问的成员变量、成员方法、构造方法。
反射的中的类加载机制是通过动态加载的方式,也就是在运行期间才对确定加载哪个类,而不是在编译期间就确定加载哪个类,这样在运行期确定加载类之后,然后通过创建字节码对象,反向获取到编译期间就加载的类中的内容,通过字节码对象分别获取到Field对象、Constructor对象、Method对象,通过这些封装的对象,获取到成员变量、构造方法、成员方法。
这就是我对反射的一些浅显理解。
注解在本质上其实就是一个接口,与类、枚举属于同一层次,是用来说明程序的,是一种给计算机看的信息。
作用主要有三个:
1.文档生成
2.编译检查,主要就是为了规范代码的编写
3.代码分析,这是最主要的功能,使用元注解将自定义的注解保留到运行的阶段,对代码进行跟踪分析,控制程序的走向,看程序的执行步骤。
它分为jdk中预定义的一些常见注解和自定义注解
预定义的常见注解有 @Override,@Deprecated,@SuppressWarnings等
其中@Override是用来检测被该注解标注的方法是否继承自父类
@Deprecaed用来标注该内容已过时,有了更好的替代
@SuppressWarnings用来压制警告的。
自定义注解的格式是:
元注解
Public @interface 注解名称{
数据类型 属性名();
}
自定义注解的格式与定义接口的格式相似,不过接口中定义的是方法,而注解中定义的是属性。
元注解是指用来描述注解的注解,本质上也是一种接口,是用来描述注解的一种接口,它分为四种:
1.@Target 用来描述注解作用位置的,ElementType.TYPE : 表示可以作用于类上
ElementType.METHOD : 表示可以作用于方法上,ElementType.FIELD : 表示可以作用于成员变量上
2.@Retention 用来描述注解被保留的阶段,也就是在什么阶段,注解会被解析出来,做什么事
3.@Documented 用来描述注解是否会被抽取到API文档中
4.@Inherited 用来描述注解是否被子类继承
注解在 Java程序中的运用主要是用来分析代码,看程序执行的方向,跟踪程序的执行,一般都是将自定义的注解保留到运行阶段,看程序在运行阶段执行的步骤,然后以此判断程序的执行是否存在错误的走向,以便程序员进行修改。
|
|