概述
动态获取程序信息以及动态调用对象的功能称为 java
语言的反射机制;得到编译以后的 class
文件对象,提供了一个 Class
类型,就是编译后的 class 类对象
反射常规开发流程
- 类名.class
- 对象.getClass
- Class.forname(“类的全名”)
- 使用类的加载器 ClassLoader
常用
Class api
有很多 api,只需要注常见的
方法名称 | 作用 |
---|---|
getName() | 获取 包名+类名 |
getSimpleName | 获取类名 |
getDeclaredConstructor(Class<?> … parameterTypes) | 根据参数,获取构造器,修饰符不影响 |
getDeclaredConstructors() | 获取全部声明的构造器,返回数组,修饰符不影响 |
总结
反射 api 很多,宏观分类
- get+要获取的东西:获取属性getField()、获取方法为 getMethod()
- 只能获取公有的
- getMethod 可以获取本类及其父类的方法
- get+Declared+获取的东西
- 获取全部的东西
- getDeclaredMethod只能获取到本类的方法
反射-创建对象
通过获取构造器,都是为了创建对象,所以 Constructor 类主要用于创建对象,jdk9
后用构造器创建对象, class.getDeclaredConstructor().newInstance(),日常开发定义的 pojo
类里面,开发规范推荐显示的写出空构造函数,一是方便通过反射创建对象,二是子类 继承父类时,默认调用 super() 保证父类有空构造函数
方法和属性
通过 class 获取方法
方法 | 说明 |
---|---|
getReturnType | 获取全部的返回值 |
getParameterTypes() | 获取全部的参数 |
getModifiers() | 获取修饰符 |
getExceptionTypes | 获取异常信息 |
操作 Filed
方法 | 说明 |
---|---|
get(Object obj) | 获取指定对象 obj 上此 Field 的属性内容 |
set(Object obj,Object value) | 设置指定对象 obj 上此 Field 的属性内容 |
暴力操作
如果反射进行相关操作,如构造器、方法、属性 没有权限怎么办?可以通过 setAccessible(true)
,修改访问权限。
invoke
运行类的指定方法步骤
- 获取 class 对象,创建对象
- 获取方法,invoke 调用
- Object invoke (Object obj, Object …args)
- 参数说明:obj是调用类的实例对象,args:调用方法的参数,是可变长度
- Object 对应原方法的返回值,若原方法无返回值,此时返回 null
- 如果原方法为静态方法,此时形参 obj 可为 null
- 如果原方法形参列表为空,则args为null
- 如果原方法声明为private,则需要在调用上 invoke 方法前,调用对象的 setAccsessible(true) 方法