一、反射概述
(一)反射就是在运行时通过代码操作类。
想要操作类,就必须先获得该类的字节码对象.Class。通过Class提供的方法对类进行进一步的解剖,从而实现各种操作。
(二)类各个组成的专业描述
Class类
Constructor 构造
Method 方法
Field 字段
instance 实例
invoke 执行
(三)JavaBean用于反射操作
Javabean规范
1.提供私有字段
2.提供get或set方法,可以使用快捷键生成
3.提供无参构造方法
4.必须要实现序列化接口 Java.io.Serializable
二、java 提供三种方式来获得Class,
不同的应用场景,需要不同的方式获得Class对象
(一)方式:
1.通过字符串(全限定类名)获得
格式:Class clazz = Class.forName("字符串");
全限定类名:包名+类名
2.通过Java类型获得
格式:Class clazz = 类型.class;
3.通过实例对象获得
格式:Class clazz = obj.getClass();
(二)应用场景:
方式1:之后开发中,从配置文件中,获得“全限定类名”,并通过反射进行所有操作
方式2:确定构造方法、普通方法形参列表时,需要通过类型获得
方式3:方法内部通过变量名获得
三、反射获得实例化对象
(一)通过无参构造方法获得实例对象
1.获得Class对象
Class clazz = Class.forName("全限定类名");
2.通过clazz获得无参构造,相当于:Bean()
//getConstructor()获得指定形参列表的构造方法
Constructor cons = clazz.getConstructor();//返回无参构造函数
3.通过构造对象获得实例化对象,相当于:new Bean()
//newInstance()创建指定实参的实例对象
Object obj = cons.newInstance();
(二)有参构造
1.获得Class对象
Class clazz = Class.forName("reflect_bean.Bean");
2.通过clazz获得无参构造,相当于:Bean()
//getConstructor()获得指定形参列表的构造方法
Constructor cons = clazz.getConstructor(String.class);//返回无参构造函数
3.通过构造对象获得实例化对象,相当于:new Bean()
//newInstance()创建指定实参的实例对象
Object obj = cons.newInstance("b002");
System.out.println(obj);
(三)无参构造的简写方式
1.获得Class对象
Class clazz = Class.forName("reflect_bean.Bean");
/2.通过clazz直接创建对象
Object object = clazz.newInstance();
(四)私有反射(暴力反射)
1.获得Class对象
Class clazz = Class.forName("reflect_bean.Bean");
2.获得指定形参私有构造
// clazz.getConstructor(...):获得指定对象指定的public构造方法
// clazz.getDeclaredConstructor(...):获得指定对象指定的任意构造方法,包含私有构造
Constructor constructor = clazz.getDeclaredConstructor(String.class,String.class);
3.通知JVM,运行实例私有构造(默认不允许)
constructor.setAccessible(true);
4.创建实例化,并设置实际参数
Object object = constructor.newInstance("b001","名称");
System.out.println(object);
三、反射普通方法
(一)public方法
1.获得实例
Class clazz = Class.forName("reflect_bean.Bean");
Object object = clazz.newInstance();
// 2.通过setId方法,设置数据
// 2.1获得方法,需要明确形参列表,setId
Method method = clazz.getMethod("setId", String.class);
// 2.2执行方法,bean。setId(...)
// 确定实例对象,并执行正确方法,具体实际参数
method.invoke(object,"b002");
// 3.通过getId方法,获得数据
Method getMethod = clazz.getMethod("getId");
String s = (String) getMethod.invoke(object);
System.out.println(s);
(二)private方法
// 1.获得实例
Class clazz = Class.forName("reflect_bean.Bean");
Object object = clazz.newInstance();
// 2.通过setId方法,设置数据
// 2.1获得方法,需要明确形参列表,setId
// clazz.getMethod(name,...):只能获得public方法
// clazz.getDeclaredMethod(name,...):获得已声明的所有方法
Method method = clazz.getDeclaredMethod("setId", String.class);
// 2.2强制设置运行访问私有访问(暴力)
method.setAccessible(true);
// 2.3执行方法,bean。setId(...)
// 确定实例对象,并执行正确方法,具体实际参数
method.invoke(object,"b002");
// 3.通过getId方法,获得数据
Method getMethod = clazz.getMethod("getId");
String s = (String) getMethod.invoke(object);
System.out.println(s);