title: 【学习之路】反射学习
draft: true
tags:
- 学习之路
- Java
- 反射
categories: - JavaSE
- 反射
description: 反射学习
cover: ‘https://cdn.jsdelivr.net/gh/CodeZixuan/Blog_Images/Reflection/bg.jpg‘
abbrlink: d7790c44
date: 2021-04-10 14:16:50
Java Reflection概述
当加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个类的对象看到类的结构。这个对象就像一面镜子透过这个镜子看到类的结构,所以,我们形象的称之为反射
Class类
在Object类中定义了以下的方法,此方法将被所有子类继承
- public fianl Class getClass()
以上方法返回值的类型必须一个Class类,此类是Java反射的源头。
- Class本身也是一个类
- Class对象只能由系统建立对象
- 一个加载的类在JVM中只有一个Class实列
- 一个Class对象对应的是一个加载到JVM中的一个.Class文件
- 每个类的实列都会记得自己是由哪个Class实列所生成
- 通过Class可以完整的得到一个类中所有被加载的结构
- Class类是Reflection的根源,针对任何你想动态加载运行的类,唯有先获得相应的Class对象
Class类中的常用方法
方法名 | 功能说明 |
---|---|
static Class forName(String name) | 返回指定类名 name 的 Class 对象 |
Object newInstance() | 调用缺省构造函数,返回该Class对象的一个实例 |
getName() | 返回此Class对象所表示的实体(类、接口、数组类、基本类型 或void)名称 |
Class getSuperClass() | 返回当前Class对象的父类的Class对象 |
Class [] getInterfaces() | 获取当前Class对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Class getSuperclass() | 返回表示此Class所表示的实体的超类的Class |
Constructor[] getConstructors() | 返回一个包含某些Constructor对象的数组 |
Field[] getDeclaredFields() | 返回Field对象的一个数组 |
Method getMethod(String name,Class … paramTypes) | 返回一个Method对象,此对象的形参类型为paramType |
ClassLoader
// 1.获取一个系统类加载器
ClassLoader classloader = ClassLoader.getSystemClassLoader();
System.out.println(classloader);
// 2.获取系统类加载器的父类加载器,即扩展类加载器
classloader = classloader.getParent();
System.out.println(classloader);
// 3.获取扩展类加载器的父类加载器,即引导类加载器
classloader = classloader.getParent();
System.out.println(classloader);
// 4.测试当前类由哪个类加载器进行加载
classloader = Class.forName("exer2.ClassloaderDemo").getClassLoader();
System.out.println(classloader);
// 5.测试JDK提供的Object类由哪个类加载器加载
classloader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classloader);
// 6.关于类加载器的一个主要方法:getResourceAsStream(String str):获取类路径下的指定文件的输入流
InputStream in = null;
in = this.getClass().getClassLoader().getResourceAsStream("exer2\\test.properties");
System.out.println(in);
获取运行时类的完整结构
获取属性结构
Class<Person> clazz = Person.class;
// 获取属性结构
// getFields():获取当前运行时类其弗雷中声明为public访问权限的属性
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("-----");
// getDeclaredFields():获取当前运行时类中所有的属性,不包含父类中的属性
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
Class<Person> clazz = Person.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
// 获取权限修饰符
int modifiers = declaredField.getModifiers();
System.out.println(Modifier.toString(modifiers));
// 获取数据类型
Class<?> type = declaredField.getType();
System.out.println(type);
// 获取变量名
String name = declaredField.getName();
System.out.println(name);
}
获取方法结构
Class<Person> clazz = Person.class;
// 获取当前运行时类及其所有父类中声明为public权限的方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
System.out.println("--");
}
// 获取当当前运行时类中的所有方法,不包括父类中的方法
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
System.out.println("--");
}
Class<Person> clazz = Person.class;
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
// 获取方法声明的注解
Annotation[] annotations = declaredMethod.getAnnotations();
for (Annotation annotation : annotations) {
System.out.print(annotation);
}
// 获取权限修饰符
System.out.print(Modifier.toString(declaredMethod.getModifiers()));
// 获取返回值类型
System.out.print(declaredMethod.getReturnType().getName());
// 获取方法名
System.out.print(declaredMethod.getName());
// 获取形参列表,参数类型
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
if (!(parameterTypes == null && parameterTypes.length == 0)){
for (int i = 0; i < parameterTypes.length; i++) {
if (i == parameterTypes.length - 1){
System.out.print(parameterTypes[i].getName() + "args_" + i);
break;
}
System.out.print(parameterTypes[i].getName() + "args_" + i + ",");
}
}
// 抛出的异常
Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();
if (exceptionTypes.length > 0){
System.out.print("throws");
for (int i = 0; i < exceptionTypes.length; i++) {
if (i == exceptionTypes.length -1){
System.out.println(exceptionTypes[i].getName());
}
System.out.println(exceptionTypes[i].getName() + ",");
}
}
System.out.println();
}