反射的作用
在运行期间动态查看、检测和修改本身状态和行为的一种能力,允许java程序在运行中动态操作类和对象的内部属性。
反射的实现
反射中最重要的三个类,都是位于java.lang.reflect目录下
- Field:域,即属性
- Method:方法
- Constructor:构造器
获取Class对象
拓展:class对象的初始化,class对象保存在哪里,类加载的时机
有三种方式:
- Class.forName("com.manoo.test.TestClass")
- TestClass.class
- getClass()
通过反射来创建对象
主要是通过newInstance()方法,实现细节上有两种方式
- 直接用Class对象进行newInstance
- 先使用Class对象获取Constructor对象,然后对Constructor对象newInstance
// 第1种方式:使用Class对象的newInstance()方法来创建Class对象对应类的实例
Class c = Date.class;
Date date1 = (Date) c.newInstance();
// 第2种方式:先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例
Constructor constructor = c.getConstructor(long.class);
Date date2 = (Date)constructor.newInstance(timestamp);
获取类的所有信息
- getDeclaredConstructors() 获取构造器信息
- getDeclaredMethods() 获得方法信息
- getDeclaredFields() 获得域信息
- getModifiers() 获取描述符信息
修改类的行为
- 修改域的值
Java反射机制-修改字段值
原理即获取Field对象,然后执行类似setInt这样的方法。 需要注意的是,如果field为私有字段,需要放开操作权限setAccessible(true) - 执行方法
-
getMethod(String name, Class<?>... parameterTypes) 获取指定的 Method
- name 为要获取的方法名
- parameterTypes 为指定方法的参数的 Class,由于可能存在多个同名的重载方法,所以只有提供正确的 parameterTypes 才能准确的获取到指定的 Method
-
invoke(Object obj, Object... args) 执行方法,第一个参数执行该方法的对象,如果是static修饰的类方法,则传null即可;后面是传给该方法执行的具体的参数值
-
spring提供的反射工具类
org.springframework.util.ReflectionUtils
提供了很多包装好的反射的工具类
反射的优缺点
优点:动态、可拓展
缺点:性能消耗、安全性、破坏对象抽象性