反射
反射概述
反射,框架设计的灵魂所在
我们知道,Java代码在计算机会经过三个阶段:源代码、字节码、运行
其中,在编译对象之前,我们的Java程序需要经过一个叫做Class类对象的阶段,在这个阶段中,变量被封装为Field[]
,构造方法被封装为Constructor[]
,成员方法被封装为Method[]
也就是在字节码中,我们可以看到Filed[]
、Constructor[]
、Method[]
反射基本概念
反射获取Class对象有几种方式:
1、Class.forName("全类名")
:将字节码文件加载到内存,存到Class对象
2、类名.class
:通过类名的属性class获取
3、对象.getClass()
:Object中存在这个方法,所以这个方法在任何的对象中都能使用
Class对象有如下功能:
1、获取成员变量
1 | // 获取所有public修饰的成员变量 |
2、获取构造方法
1 | // 获取public构造方法们 |
3、获取成员方法
1 | // 获取全部public方法 |
4、获取全类名
1 | demoClass.getName() |
Field有如下功能:
1、获取和设置值
1 | // 获取值 |
2、忽略访问权限修饰符的安全检查
1 | // 这种形式我们称为暴力反射 |
Constructor有如下功能:
1、创建对象
1 | Class<DynamicLinkDemo> demoClass = DynamicLinkDemo.class; |
Method有如下功能:
1、获取方法名称
1 | Class<DynamicLinkDemo> demoClass = DynamicLinkDemo.class; |
2、执行方法
1 | Class<DynamicLinkDemo> demoClass = DynamicLinkDemo.class; |
注解
注解概述
注解:Annotation:也就是说给计算机看的,使用的时候使用@注解名称
它在JDK5引入的一个新的特性,和类、接口、枚举在一个层面上。它可以声明在任意的类、方法、变量上,用来对这些元素进行说明和注释
注解可以通过反射读取到,那么这样就可以在调用方法之前或之后,进行方法的增强
注解基本概念
JDK中有一些预定义的注解:
1、@Override
:检测被该注解标注的方法是否是继承自父类接口的,当然不加也没有关系,这个注解主要是检查是否合乎规范的
2、Deprecate
:表示当前的内容已经过时
3、@SuppressWarnings
:压制警告
这个注解假如加到类上的时候,说明要压制类上的警告,方法同理
这个需要传递参数,一般传递
all
,这样全部的警告都不会出现:@SuppressWarning("all")
自定义注解
自定义注解的格式分两种:
1、元注解
2、public @interface 注解名称
先说我们一般的注解
它要使用@
来声明,声明的时候使用@interface
,注意不是大写I
注解类里面的抽象方法需要几个要求:
1、返回值有如下取值:
- 基本数据类型
- String
- 枚举
- 其他注解
- 以上几个类型的数组
2、使用的时候,需要赋值
假如我们在定义抽象方法的时候,假如使用
default
关键字给一个默认的初始化值,那么则使用注解的时候,可以不进行赋值,否则必须赋值假如只有一个需要赋值,并且属性的名字是value,那么value可以省略,直接定义值即可
数组赋值时,需要使用
{}
包裹,假如数组中只有一个值,那么{}
可以省略
光说不练假把式,上代码:
1 | package com.howling; |
1 |
|
demo中,可以看到标准的赋值
demo2中,可以看到age因为有一个
default
,所以省略了,那么省略之后,默认的值就是22。value假如设置一个值,就不需要{}
demo3中,可以看到name也省略了,然而因为是value所以可以省略
元注解
元注解,描述注解的注解。这样说话可能有点绕,但是它确实用于确立注解的规则
1、@Target
:描述注解可以作用的位置,使用ElementType取值
- TYPE:类上
- METHOD:方法上
- FIELD:成员变量上
2、@Retention
:描述注解被保留的阶段,一般我们使用RUNTIME,这样就会保留到字节码阶段,可以被JVM读取到
3、@Documented
:描述注解是否可以被抽取到API中
4、@Inherited
:描述注解是否可以被子类继承,只要有一个父类加上这个注解,那么它的子类全部都会继承这个注解
1 | package com.howling; |
反射获取注解
使用getAnnotation(Class)
可以获取指定的注解
1 | package com.howling.dynamiclink; |