反射机制允许程序在执行期,借助 反射API 取得任何类的内部信息,并能直接操作任何对象的内部属性及方法。
.class 文件被加载到 JVM 后,在堆内存的方法区中产生了一个 Class 类型的对象,这个对象包含了该类的结构信息。
Java 反射机制提供的功能:
- 获取有关类的一切信息(所在的包、实现的接口、标注的注解、构造器、属性、方法 等)
-
Class 类
获取 Class 的对象的方式
public void TestReflect() throws ClassNotFoundException {
// 方式1
Class<Person> clazz1 = Person.class;
// 方式2
Person person = new Person();
Class clazz2 = person.getClass();
// 方式3
Class clazz3 = Class.forName("类的路径");
// 方式4
// 获取到 ClassLoader(这里获取到的是:AppClassLoader)
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class clazz4 = classLoader.loadClass("类的路径");
}
@Test
public void TestReflect() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class clazz1 = classLoader.loadClass("com.hfy.community.entity.po.Person");
ClassLoader classLoader1 = clazz1.getClassLoader();
// 源代码中给出的基础类的简单名称。
// Person
String simpleName = clazz1.getSimpleName();
// getConstructor 只返回公共构造函数
// getDeclaredConstructor 返回所有的构造函数(不包含父类中声明的构造器)
Constructor<?>[] constructors = clazz1.getConstructors();
Constructor<?>[] declaredConstructors = clazz1.getDeclaredConstructors();
String methodName = "setName";
// 类的指定方法
Method method = clazz1.getDeclaredMethod(methodName, String.class);
String fieldName = "name";
// 类的指定属性
Field field = clazz1.getDeclaredField(fieldName);
LoginRequired annotation = (LoginRequired) clazz1.getAnnotation(LoginRequired.class);
// 类对象表示的实体(类,接口,数组类,原始类型或空白)的名称
// 即全限定类名
// class com.hfy.community.entity.po.Person
String name = clazz1.getName();
// 为此类型的名称返回一个内容丰富的字符串。
// 底层调用了 getName()
// com.hfy.community.entity.po.Person
String typeName = clazz1.getTypeName();
Annotation[] annotations = clazz1.getAnnotations();
// 类实现的接口
Class[] interfaces = clazz1.getInterfaces();
// 该类的父类
Class superclass = clazz1.getSuperclass();
// 该类的父类,带泛型
Type genericSuperclass = clazz1.getGenericSuperclass();
// 类所在的包信息
Package aPackage = clazz1.getPackage();
// com.hfy.community.entity.po
String packageName = aPackage.getName();
}
Constructor 类
@Test
public void TestReflect() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class clazz1 = classLoader.loadClass("com.hfy.community.entity.po.Person");
Constructor constructor = clazz1.getConstructor(null);
// 构造器上标注的注解
Annotation[] annotations = constructor.getAnnotations();
// 返回此对象所表示的可执行文件的 Java 语言修饰符。
int modifiers = constructor.getModifiers();
// 构造器所属的类
// class com.hfy.community.entity.po.Person
Class aClass = constructor.getDeclaringClass();
// 构造器的方法名
// com.hfy.community.entity.po.Person
String name = constructor.getName();
// 返回一个 类对象的数组,类表示由该对象表示的底层可执行文件声明的异常类型。
Class[] exceptionTypes = constructor.getExceptionTypes();
// 返回一个 Parameter 对象的数组,表示由该对象表示的底层可执行文件的所有参数。
Parameter[] parameters = constructor.getParameters();
// 构造器的参数上标注的注解
Annotation[][] parameterAnnotations = constructor.getParameterAnnotations();
}
Method 类
@Test
public void TestReflect() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class clazz = classLoader.loadClass("com.hfy.community.entity.po.Person");
Person person = (Person) clazz.newInstance();
// 当前运行时类及其父类中声明为 public 访问权限的方法
Method[] methods = clazz.getMethods();
// 当前运行时类中声明的所有方法(不包含父类中声明的方法,也包括 private 访问权限的方法)
Method[] declaredMethods = clazz.getDeclaredMethods();
// 方法的调用
Object result = methods[0].invoke(person, null);
// 方法上标注的所有注解
Annotation[] annotations = declaredMethods[0].getAnnotations();
// 方法的返回值的类型
Class<?> returnType = declaredMethods[0].getReturnType();
// 方法名
String name = declaredMethods[0].getName();
// 形参列表
Class[] parameterTypes = declaredMethods[0].getParameterTypes();
// 声明 throws 的所有异常类型
Class[] exceptionTypes = declaredMethods[0].getExceptionTypes();
}
Annotation 类
Parameter 类
Field 类
@Test
public void TestReflect() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class clazz = classLoader.loadClass("com.hfy.community.entity.po.Person");
Person person = (Person) clazz.newInstance();
// 类的属性
Field[] fields = clazz.getFields();
// 设置指定对象的属性值
fields[0].set(person, "value");
// 获取指定对象的属性值
fields[0].get(person);
// 属性上标注的所有注解
Annotation[] annotations = fields[0].getAnnotations();
// 属性的类型
Class<?> type = fields[0].getType();
// 属性的名字
String name = fields[0].getName();
// 属性的修饰符
int modifiers = fields[0].getModifiers();
}