反射与注解
文章目录
一、十六 、反射
1.1 概念
反射是一个框架的灵魂,也是实现java动态运行的一个重要支撑
可以通过反射获取到一个不固定类的信息,降低代码的耦合性。例如Java框架的使用时不需要改动源代码的,但它可以给到我们想要的类对象,使用的就是反射的原理。
编写代码的原则:高内聚、低耦合
运行期依赖,编译器不依赖
反射在运行期间可以获取到类的各个组成部分,然后封装成对象
1.1.1 Java代码的三个阶段
-
Resoure 源代码阶段
代码的编写和编译 ==> class文件
-
class文件加载成对象
在方法区内根据class文件创建出一块存放类的信息
说白了就是用一个Class类对象来表示一个类的字节码文件 -
Runtime 代码运行阶段
1.1.2反射创建对象的过程
从Java代码的编写到Java对象的运行,会经历三个阶段,分布是源代码阶段,Class类对象阶段,运行阶段,
每个类被编译成字节码文件后都会被类加载器加载到Java内存中,然后使用一个Class类对象来表现,并且这个Class对象在内存中是独一无二的,所以无论通过那种方式创建的class对象都是执行的同一个引用地址
通过反射创建对象就是利用Class类对象来创建我们需要的对象
1.2 反射的运用
1.2.1 获取class对象的方式
Class.forName(“全类名”)
将字节码文件加载进内存 返回class对象
多用于配置文件 将类名定义在配置文件中 读取文件 加载类
类名.class
通过类名的属性class获取
多用于参数的传递
对象.getClass()
getClass() 方法在Object类中定义的
多用于对象获取字节码的方式
结论
同一个字节码文件(.class)在一次程序运行的过程中 只会被加载一次 不论通过哪种方式获取的class对象都是同一个
1.2.2 获取class的成员变量
Field getField(String name)
获取指定名称的public修饰的成员变量
Field[] getFields()
获取所有public修饰的成员变量
Field[] getDeclaredFields()
获取所有的成员变量 不考虑修饰符
Field getDeclaredField(String name)
获取指定名称的成员变量 不考虑修饰符
1.2.3 获取clas对象的构造方法
Constructor getConstructor(类<?>… parameterTypes)
获取指定名称的public修饰的构造方法
Constructor<?>[] getConstructors()
获取所有public修饰的构造方法
Constructor getDeclaredConstructor(类<?>… parameterTypes)
获取指定名称的构造方法 不考虑修饰符
Constructor<?>[] getDeclaredConstructors()
获取所有构造方法 不考虑修饰符
1.2.4获取class对象的成员方法
Method getMethod(String name, 类<?>… parameterTypes)
获取指定名称的public修饰的成员方法
Method[] getMethods()
获取所有public修饰的成员方法
Method getDeclaredMethod(String name, 类<?>… parameterTypes)
获取指定名称的成员方法 不考虑修饰符
Method getDeclaredMethods()
获取所有成员方法 不考虑修饰符
1.3 反射相关的类
1.3.1 Field 成员变量类
操作:
1.设置值
void set(Object obj,Object value)
2.获取值
get(Object obj)
3.忽略访问权限修饰符的安全检查
setAccessible(true);暴力反射 成员变量对象有 构造对象也有 成员方法对象也有
1.3.2 Constructor 构造方法类
创建对象
T newInstance(Object…initargs)
如果使用空参构造方法创建对象 可以简化 Class对象newInstance的方法
1.3.3 Method 成员方法类
执行方法
method对象.invoke(Obejct obj);
获取方法的名称
String getName()
用例
public class Test01Reflect {
public static void main(String[] args) throws Ex