Java反射原理图
Java反射机制可以完成
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个对象的类
- 在运行时得到任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
- 生成动态代理
反射的优点和缺点
- 优点:可以动态的创建和使用对象(也是底层框架的核心),使用灵活,没有反射机制,底层框架就失去技术支撑
- 缺点:使用反射基本是解释执行,对执行速度又有影响
反射调用优化
- Method和Field,Constructor对象都有setAccessible()方法
- setAccessible()作用是启动和禁用访问安全检查的开关
- 参数值为True时,反射的对象在使用时取消访问检查,提高反射的效率。为False时则表示反射的对象执行访问检查
Class类对象
- Class也是类,因此也继承Object类
- Class类对象不是new出来的,而是系统创建的
- 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
- 每个类的实例都会记得自己是由哪个Class实例所生成
- 每个Class对象可以完整的得到一个类的完整结构,通过一系列API
- Class对象是存放在堆里的
Class类的常用方法
获取Class对象方式
- Class.forName()
- 类名.class,应用场景:用于传递参数
- 对象.getClass 应用场景:已知某个类的实例,通过实例获得Class对象
- 其他方式:通过类加载器获取对象 先 对象.getClass.getClassLoader()得到类加载器 再 类加载器.loadClass(classPath)
反射创建对象实例
Class<?> aClass = Class.forName("yang.pojo.Stu"); //加载类,返回Class对象
Stu stu1 = (Stu) aClass.newInstance(); //默认调用无参构造方法
System.out.println(stu1);
/* 通过有参构造创建实例!!!这里有参构造为public属性*/
Constructor<?> constructor = aClass.getConstructor(String.class, String.class, String.class);
Stu stu2 = (Stu) constructor.newInstance("ysf","20","男");
System.out.println(stu2);
/* 通过有参构造创建实例!!1这里有参构造为private属性/*/
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class, String.class, String.class);
declaredConstructor.setAccessible(true); //暴力破解
Stu stu3 =(Stu) declaredConstructor.newInstance("ysf", "20", "nan");
System.out.println(stu3);
通过反射访问类中的属性
案例:
public class FieldTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
Class<?> aClass = Class.forName("yang.pojo.Stu"); //加载类,获得加载类对象
Stu stu =(Stu) aClass.newInstance(); //通过无参构造实例化对象
Field[] fields = aClass.getFields(); //只能获得公有属性
Field[] declaredFields = aClass.getDeclaredFields(); //获得所有属性(公私有都可以)
Field name = aClass.getDeclaredField("name"); //获得name属性,此时为私有属性
name.setAccessible(true); //将私有属性name爆破
name.set(stu,"bhdx"); //.set()方法设置name属性值
String n = name.get(stu).toString(); //.get()方法访问name属性值
System.out.println(n);
}
}
通过反射访问类中的方法
案例:
public class MethodTest {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<?> aClass = Class.forName("yang.pojo.Stu"); //加载类,获得类对象
Stu stu = (Stu)aClass.newInstance(); //无参方法实例化对象
aClass.getMethods(); //只能获得公有方法
aClass.getDeclaredMethods(); // 获得所有方法,公私有方法都可
Method info = aClass.getDeclaredMethod("info"); //此时info方法为private属性
info.setAccessible(true); //强制爆破
info.invoke(stu); //调用方法
}
}