- 什么是反射
- 程序可以访问,检测和修改它本身或行为的一种能力
- JAVA反射是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,这种动态获取信息,以及动态调用对象的方法称为JAVA语言的反射机制
- 在运行是给定类的名字就可以调用类的信息,获取累的所有信息以及方法(包括私有的,实现的接口)
-
为什么要用反射机制
- 这就涉及到了动态与静态编译
类型 | 初始化方式 | 优点 | 缺点 | 备注 |
---|---|---|---|---|
静态编译 | Student s = new Student(); | 执行性能快于动态编译 | 耦合度高 | 静态编译对象,在编译时创建对象确定类型,绑定对象,即通过 |
动态编译 | Class.forName(“com.Student.class”).newInstance(); | 降低耦合度,动态编译最大限度发挥灵活性,体现了多态的应用, | 性能相对来说低 | 运行时创建对象,绑定对象, |
-
反射提供的功能
-
1.在运行时判断任意一个对象所属的类
-
2.在运行时构造任意一个类的对象
-
3.在运行时判断任意一个类所具有的成员变量和方法
-
4.在运行时调用任意一个对象的方法(包括私有)
-
-
class对象
-
Class对象是Reflection的故事的起源,要想操作类中的属性和方法,都必须从获取Class类开始
-
类是程序的一部分,每一个类都有一个class对象,编译一个新类时,就会产生一个Class对象
-
Class对象没有公共的构造方法,Class对象是在加载类是由Java虚拟机以及通过调用类加载器中的方法自动构造的,因此不能显示的声明一个class对象
-
-
获取class对象
- reflect API
/**
抛出的异常
throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException,
SecurityException, IllegalArgumentException, InvocationTargetException
*/
/**
* getMethod(String name, Class<?>... parameterTypes)
* 1.指定方法
* 2.name:方法名称
* 3.parameterTypes方法接受参数类型注意顺序
* invoke(Object obj, Object... args)
* 1.如果有返回值的情况下,获取的方法将返回值付给invoke
* 2.obj参数:那个对象的方法
* 2.args:这个参数在class对象获取方法时的,设置参数类型的个数以及顺序
*/
Class<?> forName = Class.forName("reflect.Student"); //创建对象实例
Object newInstance = forName.newInstance(); //初始化对象
Method method = forName.getMethod("setName", String.class); //获取方法设置对象中的方法名以及接受参数类型
method.invoke(newInstance, "a"); //赋值,invoke(Object obj, Object... args) obj那个对象里的方法,args方法接受参数
Method method2 = forName.getMethod("getName", null); // 获取方法
Object invoke = method2.invoke(newInstance);
System.out.println(invoke.toString());
Class<?> forName = Class.forName("reflect.Student"); //创建对象实例
Object newInstance = forName.newInstance(); //初始化对象
Field declaredField = forName.getDeclaredField("name"); //获取私有属性
declaredField.setAccessible(true); //设置取消语言访问检查,私有属性也可以修改值
declaredField.set(newInstance, "a"); //设置私有属性值
System.out.println(declaredField.get(newInstance));