这是我参与「第四届青训营 」笔记创作活动的第4天
反射可以直接操作类的内部属性和方法,因此反射会破坏程序的封装性
主要有以下几个 作用
- 获取Class对象
- 获取类中的成员变量(字段)field
- 获取方法 Method
- 获取构造方法 Constructor
反射是框架设计的灵魂
反射是所有注解实现的原理
获取Class对象
三种方式
//获取class对象
//1.通过类的路径名获取
Class beanClass=Class.forName("com.yxl.reflection.Bean");
System.out.println(beanClass);
//2.通过类名的形式获取(需要导包)
Class beanClass2= Bean.class;
System.out.println(beanClass2);
//3.通过bean对象获取
Bean bean=new Bean();
Class beanClass3=bean.getClass();
System.out.println(beanClass3);
反射的基础就是基于Class对象,只有获取了Class对象才能继续进行反射的其他操作
获取成员变量
getDeclaredFields
获取所有的字段,包括共有和私有
Field[] declaredFields = beanClass.getDeclaredFields();
Field name = beanClass.getDeclaredField("name");
getFields
获取所有的共有字段
使用
Field name = beanClass.getDeclaredField("name");
name.setAccessible(true);
name.set(bean,"huahua");
System.out.println(name.get(bean));
通过set 和get来设置和获取
同时还需要一个bean类的实例对象
可以通过获取构造方法来获取对象实例
setAccessible启用和禁用访问安全检查的开关,值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
获取构造方法
Constructor[] declaredConstructors = beanClass.getDeclaredConstructors();
for (Constructor c: declaredConstructors) {
System.out.println(c);
}
使用
Constructor constructor = beanClass.getDeclaredConstructor(String.class);
constructor.setAccessible(true);//表示可以使用
Bean beanb = (Bean) constructor.newInstance("xiaolong");
beanb.setAge(10);
System.out.println(beanb);
获取方法
// 1.获取所有声明的函数
Method[] declaredMethodList = studentClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethodList) {
System.out.println("declared Method: " + declaredMethod);
}
// 2.获取所有公有的函数
Method[] methodList = studentClass.getMethods();
for (Method method : methodList) {
System.out.println("method: " + method);
}
使用
Method method=beanClass.getDeclaredMethod("show", String.class);
method.setAccessible(true);
Object message = method.invoke(beanb, "message");
System.out.println(message);
invoke 方法来使用通过反射来获取的方法 ,需要传入一个对象实例和方法所需的参数
这里要注意的是直接通过反射获取子类的对象是不能得到父类的属性值的,必须根据反射获得的子类 Class 对象在调用 getSuperclass() 方法获取父类对象,然后在通过父类对象去获取父类的属性值