反射
-
动态语言
是一类可以在程序运行过程中改变其结构的语言。比如说定义的方法、对象、一些功能代码可以在程序运行中被加载进去,从而达到修改或者删除已有的方法和数据
动态语言:JavaScript(脚本语言)、PHP 、Python、C#等等
-
静态语言
与动态语言相比,运行时程序结构不发生改变的语言就是静态语言。 如C、C++、Java等
Java虽不是动态语言,但是称之为“准动态语言”,可以利用反射机制来动态的获取类结构信息并且修改类结构信息。Java的动态性使开发更加灵活。
反射概述
-
Reflection,在程序中主要是借助Reflection API获取类结构的内部信息,并且能够直接操作类结构内部信息(属性和方法) 如:Class.forName(“com.mysql.jdbc.Driver”);// 硬编码
-
类加载进内存后,在堆存当中就产生了一个Class类型对象(一个类在内存当中有且只有一个Class对象),这个对象就包含了完整的类的结构信息。(属性、方法、构造方法、类名、静态信息等等)。我们可以通过这个对象看到类的内部结构。这个对象就像一面镜子一样。透过这个镜子可以看到类的内部结构。这种形式,我们形象的称之为“反射机制”。
-
反射一般把它当成框架的灵魂
框架:半成品软件,我们可以在框架的基础上进行开发,简化代码
-
好处:
- 可以在程序运行过程中 ,动态的操作这些对象
- 可以达到解耦,提高程序的可扩展性。
-
借助于Class类、Method类、Filed类、Constructor类实现反射
反射常用API操作
获取Class对象:有三种方式
- Class.forName(“类的全路径”):将字节码文件加载进内存当中,返回Class对象
- 多用于读取配置文件 xml/properties,将类名,方法名,用户名等等配置到文件中
- 类名.class :通过类名的属性class获取Class对象
- 多用于参数传递
- 对象.getClass():通过getClass()方法获取Class对象,getClass() 是Object类中的方法
- 常用于获取对应的字节码对象
- 总结:不论是通过哪种方式获取到的,同一个字节码文件在一次程序运行过程中,只会生成一个Class对象
Method对象、Field对象、Constructor对象
属性对象
-
获取属性对象
- Field getField(String name)
返回一个 Field对象,它反映此表示的类或接口的指定**公共成员字段 **类对象。 - Field[] getFields()
返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。 - Field getDeclaredField(String name)
返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。 不限制权限修饰符 - Field[] getDeclaredFields()
返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。 不限制权限修饰符
- Field getField(String name)
-
设置属性对象值
void set(Object obj,Object value):第一个参数是对应的实际对象,第二个参数是需要设置的值
-
获取属性对象值
Object get(Object obj) : 获取对应的属性值
-
忽略访问权限修饰符的安全性检查:关闭访问权限
setAccessiable(boolean flag) 传入true值,关闭访问权限,传入false值,打开访问权限
构造对象
-
获取构造对象
- Constructor getConstructor(类<?>… parameterTypes)
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。 - Constructor<?>[] getConstructors()
返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。 - Constructor getDeclaredConstructor(类<?>… parameterTypes)
返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。 - Constructor<?>[] getDeclaredConstructors()
返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类
- Constructor getConstructor(类<?>… parameterTypes)
-
构建对象
T newInstance(Object … initargs)
-
如果想使用空参构造,有两种方式:
第一种可以使用Class类中newInstance() 第二种可以使用Constructor类中的newInstance()
通常使用第一种方式。
方法对象
- 获取方法对象
- Method getMethod(String name, 类<?>… parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。 - Method[] getMethods()
返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。 - Method getDeclaredMethod(String name, 类<?>… parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。 - Method[] getDeclaredMethods()
返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
- Method getMethod(String name, 类<?>… parameterTypes)
- 执行方法
- Object invoke(Object obj,Class … parametertype)
- 获取方法的名称
- String getName()