- 底层的技术----反射技术
反射 reflect
-
面向对象的变成思想:
类——从很多对象中抽取出来的公有的特征行为,抽象描述一组对象
对象;现实生活中 ,先存在了好多对象,很多相同特征,相同行为。 -
放射:
类是用来描述一组对象;
反射机制认为是用来描述一组类;
描述类的类 | 描述 |
---|---|
Class | 用来描述类本身 |
Package | 用来描述类所属的包 |
Field | 用来描述类中的属性 |
Method | 用来描述类中的方法 |
Constructor | 用来描述类中的构造方法 |
Annotation | 用来描述类中的注解 |
获取Class
类的对象
- 如何获取Class类对象[ 用 来 描 述 另 一 个 类 用来描述另一个类 用来描述另一个类],如下三种方式
Class clazz = Class.forName("包名.类名");
传 参 类 全 名 传参类全名 传参类全名Class clazz = 类名.class;
Class clazz = 对象.getClass();
O b j e c t 类 中 的 方 法 Object类中的方法 Object类中的方法
-
clazz
类对象
Class中的常用方法
int modifier = clazz.getModifiers();
获 取 类 的 修 饰 符 ( 多 个 修 饰 符 返 回 对 应 整 数 之 和 ) 获取类的修饰符(多个修饰符返回对应整数之和) 获取类的修饰符(多个修饰符返回对应整数之和)String name= clazz.getName();
获 取 类 的 全 名 ( 包 名 . 类 名 ) 获取类的全名(包名.类名) 获取类的全名(包名.类名)String cName= clazz.getSimpleName();
获 取 类 简 单 名 ( 只 有 类 名 , 缺 少 包 名 ) 获取类简单名(只有类名,缺少包名) 获取类简单名(只有类名,缺少包名)Class superClass= clazz.getSuperClass();
获 取 当 前 类 父 类 的 对 应 C l a s s 对 象 获取当前类父类的对应Class对象 获取当前类父类的对应Class对象Class[] interfaceClass= clazz.getInterfaces();
获 取 当 前 类 父 亲 接 口 获取当前类父亲接口 获取当前类父亲接口Package package = clazz.getPackage();
获 取 当 前 类 所 属 的 包 获取当前类所属的包 获取当前类所属的包Class[] innerClass= clazz.getClasses();
获 取 类 中 的 内 部 类 获取类中的内部类 获取类中的内部类Method method = clazz.getMethod("方法名",Class...参数类型);
获 取 公 有 的 方 法 ( 本 类 + 父 类 ) 获取公有的方法(本类+父类) 获取公有的方法(本类+父类)Constructor constructor = clazz.getConstructor(Class...参数类型);
获 取 构 造 方 法 获取构造方法 获取构造方法
获取修饰符
getModifiers()
modifier
:/ˈmɒdɪfaɪə(r)/
:n. 修饰语;int result = clazz.getModifiers();
获取类的修饰符(权限,特征)
每一个修饰符用一个整数来进行表示:
用0,1,2,4,8 ,16,32,64,128,256,512这几个整数表示修饰符:
int: | 表示修饰符 | int: | 表示修饰符 | int: | 表示修饰符 | int: | 表示修饰符 |
---|---|---|---|---|---|---|---|
0 | 默认不写 | 1 | public | 2 | private | 4 | protected |
8 | static | 16 | final | 32 | synchronized | 64 | volatile |
128 | transient | 256 | native | 512 | interface | 1024 | abstract |
获取类名字
-
getName()
,getSimpleName()
;
String name = clazz.getName();//获取名字,类全名
String simpleName = clazz.getSimpleName();//简单名,类名
Package p = clazz.getPackage();//先获取Package对象
p.getName();//再由对象获取包名
Class sclazz = clazz.getSuperClass();//获取超类(父类)的描述对象
Class[] classes = getInterface();//获取接口的描述对象,返回一个Class集合
通过Class对象获取对象
Object obj = clazz.newInstance();//默认调用无参数构造方法创建对象
//推荐通过获取构造方法描述对象,来创建对象;
操作类属性
- Field 类属性的描述类;
获取公有属性
-
getField("属性名")
,getFields()
;只能获取公有的属性对象,包含继承过来的父类属性对象;
Field field = Clazz.getField("属性名");//需要得知属性名
Field[] fs = Clazz.getFields(); //获取公有属性对象集合
//如上的两个方法只能获取公有的属性,但是包含继承过来的父类属性
获取私有属性
-
getDeclaredField("属性名")
,getDeclaredFields()
;
Declared
:/dɪˈkleəd/
:adj. 公然的;以声名的;
这两个方法能获取公有的和私有的属性对象,但是只能获取本类中的属性的对象
Field field = clazz.getDeclaredField("属性名");
Field[] fs = clazz.getDeclaredFields();
获取属性对象测试:
- 类1
package reflectTest;
public class Base {
public String public_Base;
String 默认不写_Base;
protected String protected_Base;
private String private_Base;
public static String public_static_Base;
static String static_Base;
protected static String protected_static_Base;
private static String private_static_Base;
}
- 类2
package reflectTest;
public class Test extends Base{
public String public_Test;
String 默认不写_Test;
protected String protected_Test;
private String private_Test;
public static String public_static_Test;
static String static_Test;
protected static String protected_static_Test;
private static String private_static_Test;
}
-
执行代码1
调用
getFields()
;
Class clazz=Class.forName("reflectTest.Test");
Field[] field= clazz.getFields();
for(Field v:field) {
System.out.println(v.getName());
}
- 代码1输出
public_Test
public_static_Test
public_Base
public_static_Base
- 执行代码2
Class clazz=Class.forName("reflectTest.Test");
Field[] field =clazz.getDeclaredFields();
for(Field v:field) {
System.out.println(v.getName());
}
-
代码2输出
public_Test
默认不写_Test
protected_Test
private_Test
public_static_Test
static_Test
protected_static_Test
private_static_Test
Field类实例基础方法
-
Field field = clazz.getField("属性名")
;
int modifer =field.getModifers();
//获取属性的修饰符,用int的整数表示
String fName =field.getName();
//获取属性名字
Class clazz =field.getType();
//获取属性类型的类的描述对象
操作属性存取值
-
Object obj = clazz.newInstance()
; - 操作类实例化后,操作对象属性;
-
set(对象,值)
,get(对象)
;
Field f = clazz.getField("属性名");
f.set(obj,值);
//设置对象的值
f.get(obj);
//获取对象的值
操作私有属性
-
判断是否可以操作
isAccessible()
; 正 常 情 况 属 性 私 有 只 有 本 类 有 操 作 权 限 正常情况属性私有只有本类有操作权限 正常情况属性私有只有本类有操作权限 -
setAccessible(true)
;accessible
:/əkˈsesəbl/
:adj. 可以接近的;可以接触的;
Filed f =clazz.getDeclaredField("属性名");
if(f.isAccessible() == false)f.setAccessible(true);
//假如是私有属性,设置可操作
f.set(obj,值);
操作类中的方法
-
Class clazz = Class.forName("包名.类名");
传 参 类 全 名 , 获 取 类 描 述 对 象 传参类全名,获取类描述对象 传参类全名,获取类描述对象
获取类中方法的描述对象;
-
Method method = clazz.getMethod("方法名",Class...参数类型);
获 取 公 有 的 方 法 ( 本 类 + 父 类 ) 获取公有的方法(本类+父类) 获取公有的方法(本类+父类) -
Method method = clazz.getDeclaredMethod("方法名",参数类型的class...);
获 取 一 个 方 法 ( 本 类 定 义 的 方 法 ) 获取一个方法(本类定义的方法) 获取一个方法(本类定义的方法) -
Method[] methods = clazz.getDeclaredMethods();
获 取 本 类 定 义 的 全 部 的 方 法 获取本类定义的全部的方法 获取本类定义的全部的方法
获取构造方法的描述对象
-
Constructor constructor = clazz.getConstructor();
获 取 p u b l i c 修 饰 的 无 参 构 造 方 法 获取public修饰的无参构造方法 获取public修饰的无参构造方法
-
Constructor constructor = clazz.getConstructor(Class...参数类型);
获 取 p u b l i c 修 饰 的 参 数 列 表 对 应 的 构 造 方 法 获取public修饰的参数列表对应的构造方法 获取public修饰的参数列表对应的构造方法
-
Constructor[] constructors = clazz.getConstructors();
获 取 p u b l i c 修 饰 的 全 部 构 造 方 法 获取public修饰的全部构造方法 获取public修饰的全部构造方法
-
Constructor constructor = clazz.getDeclaredConstructor([Class...参数类型]);
获 取 定 义 的 无 参 [ 有 参 ] 的 构 造 方 法 获取定义的无参[有参]的构造方法 获取定义的无参[有参]的构造方法
-
Constructor[] constructors = clazz.getDeclaredConstructors();
获 取 全 部 定 义 的 构 造 方 法 获取全部定义的构造方法 获取全部定义的构造方法
创建对象
Object obj = constructor.newInstance([参数...]);
Method类中的常用方法
Method method = clazz.getMethod("方法名"[,参数类型Class...]);
-
int modifier = method.getModifiers();
获 取 方 法 的 修 饰 符 ( 权 限 + 特 征 ) 获取方法的修饰符(权限+特征) 获取方法的修饰符(权限+特征);
-
Class returnType = method.getReturnType();
获 取 返 回 值 类 型 获取返回值类型 获取返回值类型
-
String mName = method.getName();
获 取 方 法 的 名 字 获取方法的名字 获取方法的名字
-
Class[] mpts = method.getParameterTypes();
Parameter
:/pəˈræmɪtə(r)/
:n. 参数;系数;参量;获 取 参 数 列 表 的 C l a s s 对 象 获取参数列表的Class对象 获取参数列表的Class对象
-
Class[] exceptions = m.getExceptionTypes();
获 取 方 法 抛 出 的 异 常 的 C l a s s 对 象 列 表 获取方法抛出的异常的Class对象列表 获取方法抛出的异常的Class对象列表
使方法执行
-
method.invoke(对象[,参数...]);
Object obj = clazz.newInstance();
method.invoke(obj[,参数...]);
调 用 无 参 的 方 法 调用无参的方法 调用无参的方法;获 取 的 是 私 有 方 法 : 获取的是私有方法: 获取的是私有方法:
Method method = clazz.getDeclaredMethod("方法名"[,类型Class...]);
method.setAccessible(true);
method.invoke(obj[,参数...]);
Constructor类中的常用方法
Constructor constructor = clazz.getConstructor();
-
int modifier = constructor.getModifiers();
获 取 修 饰 符 获取修饰符 获取修饰符
-
String cName = constructor.getName();
获 取 方 法 名 字 获取方法名字 获取方法名字
-
Class[] cpts = constructor.getParameterTypes();
获 取 参 数 列 表 的 C l a s s 对 象 获取参数列表的Class对象 获取参数列表的Class对象
-
Class[] exceptions = constructor.getExceptionTypes();
获 取 构 造 方 法 抛 出 的 异 常 的 C l a s s 对 象 列 表 获取构造方法抛出的异常的Class对象列表 获取构造方法抛出的异常的Class对象列表
使构造器执行
-
Object obj = constructor.newInstance([参数...]);
执 行 私 有 构 造 方 法 : 执行私有构造方法: 执行私有构造方法:
constructor.setAccessible(true);
Object obj = constructor.newInstance([参数...]);