目录
1、反射机制的定义;
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2、获取Class(反射)的三种方式;
//1.通过new对象实现反射机制
Student stu = new Student();
Class classobj1 = stu.getClass();
System.out.println("方式一:" + classobj1.getName());
//2、通过类路径实现反射机制
Class classobj2 = Class.forName("fangdong.Student");
System.out.println("方式二:" + classobj2.getName());
//3、通过类名实现反射机制
Class classobj3 = Student.class;
System.out.println("方式三:" + classobj3.getName());
3、通过反射获取实例化对象;
class对象.newInstance();
4、反射中常用的方法;
newInstance() | 获取实例化对象 |
getName() | 获取带包名的完整类名 |
getSimpleName() | 获取类名 |
getFields() | 获取public修饰的属性(返回值FIled数组) |
getDeclaredFields() | 获取所有的属性(返回值FIled数组) |
getDeclaredField(String name) | 获取指定名字的属性 |
getModifiers() | 获取属性的修饰符列表,返回值是一个int型数字 |
getDeclaredMethods() | 获取所有实例方法(返回值Method[]) |
getDeclaredMethod(String name, Class<?>… parameterTypes) | 根据方法名name和方法形参获取指定方法 |
getDeclaredConstructors() | 获取所有构造方法 |
getDeclaredConstructor(Class<?>… parameterTypes) | 根据方法形参获取指定的构造方法 |
getSuperclass() | 获取调用类的父类 |
getInterfaces() | 获取调用类实现的接口集合 |
getName() | 获取属性名 |
getType() | 获取返回属性类型 |
set(Object obj, Object value) | 设置属性值 |
get(Object obj) | 读取属性值 |
5、反射获取属性和方法示例
反射获取并设置属性;
//获取反射
Class stuclass = Student.class;
Object ob = stuclass.newInstance();
//获取指定名字的属性(包括私有的)
Field f1 = stuclass.getDeclaredField("name");
//获取和设置属性值
f1.set(ob, "");
//特别提示--为私有属性时,需要打破封装才可以进行set操作
f1.setAccessible(true);
f1.get(ob);
//获取public属性
Field[] fields = stuclass.getFields();
反射获取方法并执行;
//获取反射
Class stuclass = Student.class;
Object ob = stuclass.newInstance();
//获取所有的方法(包括私有的)
Method[] methods = stuclass.getDeclaredMethods();
for(Method m : methods){
//获取返回值类型
m.getReturnType().getSimpleName();
//获取方法名
m.getName();
//调用方法
m.invoke(ob, "参数1", "参数2");
}
6、反射API文档;
官方文档
https://docs.oracle.com/javase/tutorial/reflect/index.html
7、反射的常见应用场景;
jdbc连接数据库、spring框架中通过反射来装载bean;
8、反射的缺点
反射是强大的,但不应该被滥用。如果可以在不使用反射的情况下执行操作,那么最好避免使用反射。当通过反射访问代码时,应该记住以下问题。
性能开销
因为反射涉及动态解析的类型,所以某些Java虚拟机优化无法执行。因此,反射操作的性能比非反射操作慢,应该避免在对性能敏感的应用程序中频繁调用的代码段中使用。
安全限制
反射需要运行时权限,而在安全管理器下运行时,该权限可能不存在。对于必须在受限的安全上下文中运行的代码,例如在Applet中,这是一个重要的考虑因素。
内部构件暴露
因为反射允许代码执行在非反射代码中非法的操作,如访问private
字段和方法,反射的使用可能会导致意想不到的副作用,这可能会导致代码功能失调,并可能破坏可移植性。反射代码打破了抽象,因此可能会随着平台的升级而改变行为。