Java反射在java.lang.reflect包中,具有分析类的能力,可以检查类的结构。
1. 反射
反射之所以被称为框架的灵魂,主要是因为它赋予了在运行时分析类以及执行类中方法的能力。
通过反射可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。
1.1. 应用场景
Spring,Spring Boot,MyBatis等框架中大量使用了反射机制
而框架中大量使用的注解也用到了反射。
为什么使用 Spring 的时候 ,一个@Component
注解就声明了一个类为 Spring Bean 呢?为什么你通过一个 @Value
注解就读取到配置文件中的值呢?究竟是怎么起作用的呢?
这些都是因为基于反射分析类,然后获取到类/属性/方法/方法的参数上的注解。
1.2. 案例
1 | class User{ |
2. 获取class实例
java.lang.class
允许程序在运行时进行自我检查,同时也允许对其内部的成员进行操作。得到一个对象所属的类,获取一个类的所有成员变量和方法,在运行时创建对象,调用对象的方法。
获取class类(专门的java类访问运行时类型信息):
class.forName(“包名.类名”);
类名.class;
实例.getClass()
ClassLoader.loadClass(“包名.类名”)
通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一些列步骤,静态块和静态对象不会得到执行
实例化:必须有public的无参构造器,class.newInstance()
1 | //调用运行时类的属性 |
3. 哪些类型可以有class对象
class:外部类,成员内部类,静态内部类,局部内部类,匿名内部类
interface:接口
1
Class c = Comparable.class;
[]:数组
1
2
3
4int[] arr = new int[10];
Class<? extends int[]> arrClass = arr.getClass();
Class c = String[].class;enum:枚举
1
Class<Enum> e = Enum.class;
annotation:注解@interface
1
Class user = Override.class;
primitive type:基本数据类型
1
Class<Integer> i = Integer.class;
void
1
Class<Void> v = Void.class;
4. 分析类
java.lang.reflect
setAccessible(true)
所有域设置为可访问,屏蔽访问检查
4.1. Field域
获取Field对象方式:
- getFields() 当前运行时类及其父类中声明为public访问权限的属性
- getDeclaredFields() 运行时类的所有属性,不包含父类,包含private
- getField(String name) 返回指定名称的属性
Field可用操作:
get(Object) 返回对象中属性的值
getType() 属性的类型
getModifiers() 属性权限修饰符
public class Modifier
权限 值 default 0 public 1 private 2 protected 4 static 8 final 10 synchronized 20 volatile 40 transient 80 native 100 interface 200 abstract 400 enum 4000 synthetic 1000 mandated 8000
代码
1 | class User{ |
4.2. Method方法
Method[] getMethods() 当前运行时类及其父类中声明为public访问权限的方法
Method[] getDeclaredMethods() 当前运行时类的所有属性,不包含父类,包含private
Method getDeclaredMethod(方法名,参数类型) 所有定义的方法
Class[] getReturnType() 返回值类型
Annotation[] getDeclaredAnnotations() 方法上的所有注解
Class[] getParameterTypes() 方法行参列表
Class[] getExceptionTypes 方法异常列表
Method getMethod(函数名,参数)
1
Math.class.getMethod("sqrt",double.class);
invoke(Object obj, Object… args) 调用当前对象中的方法
1
2
3Employee c = new Employee("A");
Method m = Employee.class.getMethod("getName");
String str = (String)m.invoke(c);
4.3. Constructor构造器
- getConstructors() 当前运行时类中声明为public的构造器
- getConstructor(Class<?>… parameterTypes) 带参数的构造器
- getDeclaredContructors() 所有构造器
- getParameterTypes() 参数类型 Class[]
- Type getGenericSuperclass() 泛型父类
- Type getSuperclass() 父类
4.3.1. 得到父类的泛型
getGenericSuperclass()
1 | class Father<T>{ |