底层的技术----反射技术

  • 底层的技术----反射技术

反射 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([参数...]);


上一篇:json存数据库时处理器,jsonHandler/jsonArrayHandler


下一篇:Spring源码解析2