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();}
