- 概念
反射就是一些高级的API,反射是java这门语言比较有特点的一个特征,可以通过反射获取目标类中的一些资源,并且创建对象。
二、获取字节码对象三种方式
- Class for Name(“包名 类名”));
- 类名.class;
- 对象名.get class();
- 获取包名、类名
clazz.get name /获取完整类名
clazz.get package().get name() /获取包名
clazz.get simple Name() / 获取类名
获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)
获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)
反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(666,”海绵宝宝”);//执行含参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法
反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null
反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法
三、反射代码总结
1.反射的操作前提是获取字节码对象
三种方式 : Class.for Name(“包名 类名”);
类名.class;
类的实例对象get.class();
- 带class的是字节码对象,带package 的是包对象。
- 获取指定类的构造方法
这个方法的返回值类型是一个数组,数组中存着的是多个构造函对象
get parameterTypes(); 获取参数列表,打印的时候用Arrays.to String();
- 通过反射创建指定类的对象
方式一、
- 先获取字节码对象
- 通过字节码对象之间调用newInstance(),触发目标类的无参构造创建对象。
方式二、
- 先获取指定参数类型的构造函数对象,在通过获取到的这个构造函数调用newInstance(参数列表);
- 注意:在获取这个构造函数指定参数类型的时候,参数传入的是字节码对象,不是普通的类型。
- 获取与调用私有方法
- get.DeclaredMethod(m,x,y,z....)
m:你要获取哪个方法名,x,y,z可变参数,因为类型不确定,此处传入的是字节码对象,不能直接传入类型。
- 没有对象时就通过反射的方式创建对象
- Invoke(o,x,y,z....)这个方法的作用是通过反射执行获取到的方法。
O:代表的是哪个对象的方法 。 x,y,z.... 执行这个方法时需要传入的参数。
- 要想执行私有方法,必须要设置私有可见。
setAccessible(true); 暴力反射