Java反射-反射API、类加载过程 短命女 2023-10-13 16:09 11阅读 0赞 ##### 反射 ##### Java反射API是Java语言实现动态性的关键,它允许动态的创建对象、赋值、以及调用对象的方法,同时反射也是实现动态代理的关键,涉及到反射相关的几个类主要有 Class、ClassLoader,Field、Method、Constructor、Proxy等。因为在Java中一切皆对象,当然,编译后的class字节码文件也会被JVM创建出一个唯一的Class类型对象,类就是类,对象就是对象,对象有属性可以调方法,任何对象也不例外,无需把这些对象想复杂化。 ##### 反射的几个API使用 ##### * 获取Class对象的几种方式 //一、获取class的几种方式 Class<?> cls1 = Class.forName("com.example.module01.reflect.Human"); //常用于动态的加载某个class,例如从配置文件获取 Class<Human> cls2 = Human.class;//常用于调用某个需要class类型参数的方法时的参数传递 Class<? extends Human> cls3 = new Human().getClass();//常用于在明确类型的情况下获取class Class<?> cls4 = RefTest01.class.getClassLoader().loadClass("com.example.module01.reflect.Human");//常用于动态 System.out.println(cls1 == cls2 ? cls1 == cls3 ? cls1 == cls4 : "不相等" : "不相等"); //true * Constructor类API // 2.1 构造方法相关 Class<Student> clazz = Student.class; Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); System.out.println("声明的构造方法个数:" + declaredConstructors.length); Constructor<?>[] constructors = clazz.getConstructors();//获取所有的构造方法 for (Constructor<?> constructor : constructors) { Class<?> declaringClass = constructor.getDeclaringClass();//获取此构造方法的声明类 Class<?>[] parameterTypes = constructor.getParameterTypes();//获取不带泛型的构造方法 Type[] genericParameterTypes = constructor.getGenericParameterTypes();//获取带泛型的构造方法 Object instance = null; // instance = constructor.newInstance();//调用newInstance System.out.println("构造方法的声明位置:" + declaringClass + ",构造方法参数个数:" + parameterTypes.length + ",带泛型的构造方法参数个数:" + genericParameterTypes.length + ",创建的对象:" + instance); } * Method API //2.2 method方法API Method[] methods = clazz.getMethods(); //可以获取所有的公开的方法,包括本类的和继承的 for (Method method : methods) { System.out.println("公开的方法:" + method.getName() + "," + method.getDeclaringClass()); } Method[] declaredMethods = clazz.getDeclaredMethods();//获取声明在本类中的所有方法,包括静态方法 for (Method declaredMethod : declaredMethods) { declaredMethod.setAccessible(true);//破解private权限 declaredMethod.invoke(clazz.newInstance());//反射执行方法 System.out.println("本类所有方法:" + declaredMethod); } System.out.println("========================Field======================="); * Field API //2.3 属性相关 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println("公开的属性:" + field.getName()); } for (Field declaredField : clazz.getDeclaredFields()) { Student student = clazz.newInstance(); declaredField.setAccessible(true);//设置可访问 declaredField.set(student,1);//给属性赋值 Object value = declaredField.get(student); System.out.println("本类的所有属性:" + declaredField.getName() + " val ===> " + value); } * 获取父类 接口API相关信息,通过获取superClass给继承的父类属性赋值 //2.4获取父类、接口信息 Class<? super Student> superclass = clazz.getSuperclass(); Class<?>[] interfaces = clazz.getInterfaces(); System.out.println("父类是:" + superclass); //Object类的superClass是null。 System.out.println("本类实现的接口:" + interfaces.length); //2.5 实现Spring自动注入效果,将父类的protected类型属性也自动注入。 Class<Student> stuClass = Student.class; //通过反射创建对象 Student instance = stuClass.newInstance(); //获取本类的方法 for (Field field : stuClass.getDeclaredFields()) { //开启访问权限 field.setAccessible(true); //动态赋值 field.set(instance,111); } //继续获取父类的class对象 Class<? super Student> superClass = stuClass.getSuperclass(); //继续获取父类的成员属性 Field[] declaredFields = superClass.getFields(); for (Field declaredField : declaredFields) { //给父类属性赋值 declaredField.set(instance,222); } //打印输出 System.out.println(instance); * Class类的几个重要方法 1. isAssignableFrom 用于判断两个Class对象是否有继承或者实现关系。 2. Reflection.getCallerClass 获取调用当前方法的Class对象 3. 在使用反射为静态属性赋值或者调用静态方法时 可以不传target实例对象。 ##### Class类加载过程 ##### ![在这里插入图片描述][a4195b060a494f539c6cbf23132e1620.png] Java类加载主要分为这么几个阶段 * 编译阶段 将.java源文件编译成.class字节码文件。 * 运行阶段 1. 当JVM第一次加载某一个用到的类时,会使用ClassLoader类加载器加.class文件加载到内存中。 2. 连接-验证阶段:对class进行验证 头文件元数据等。 3. 连接-准备阶段:收集字节码中的静态属性与静态代码块,并把静态属性赋值默认值。 4. 连接-解析阶段:解析阶段主要是把符号引用转换为地址应用。 5. 初始化:初始化阶段主要是运行class的静态代码块内容。 所有阶段都运行完成之后,此时JVM会把二进制的class文件加载到方法区,同时创建一个Class对象放入堆区。这个时候仅仅是完成了类的加载过程,之后才是创建对象。 [a4195b060a494f539c6cbf23132e1620.png]: https://img-blog.csdnimg.cn/a4195b060a494f539c6cbf23132e1620.png
相关 Java反射API使用案例:动态加载类 在Java中,反射API允许我们在运行时检查类、方法和字段等信息。下面是一个使用Java反射API动态加载类的简单示例: ```java import java.lang.r 我不是女神ヾ/ 2024年09月11日 08:09/ 0 赞/ 20 阅读
相关 Java反射API探析:类加载错误案例 在Java中,反射API允许我们在运行时获取、修改或创建对象的内部信息。然而,如果使用不当,可能会引发类加载错误。 下面是一个类加载错误案例: 1. 创建一个未通过编译的类 深藏阁楼爱情的钟/ 2024年09月10日 16:18/ 0 赞/ 24 阅读
相关 类加载器&反射 1.类加载器 1.1 类加载【理解】 类加载的描述 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接, 矫情吗;*/ 2024年04月08日 11:16/ 0 赞/ 39 阅读
相关 类加载&反射机制 目录 类加载 类的执行过程 类初始化的步骤 类的初始化时机 类加载器 类加载器的作用 获取Class对象的三种方法 反射机制 反射API Class类的 水深无声/ 2024年04月01日 19:14/ 0 赞/ 51 阅读
相关 Java反射-反射API、类加载过程 反射 Java反射API是Java语言实现动态性的关键,它允许动态的创建对象、赋值、以及调用对象的方法,同时反射也是实现动态代理的关键,涉及到反射相关的几个类主要有 Cl 短命女/ 2023年10月13日 16:09/ 0 赞/ 12 阅读
相关 Java注解和反射(三)类加载过程 前言 学习了类加载过程,可以更加方便我们理解反射的机制和原理。没兴趣的同学可直接跳过该篇。 一、类加载过程 1、加载(load) 将class文件字节码内容 今天药忘吃喽~/ 2022年11月04日 00:56/ 0 赞/ 113 阅读
相关 反射_类加载器 类的加载过程 当程序主动使用某个类的时候,如果该类还没有被加载到内存中,则系统会通过如下步骤对类进行初始化。 ![70][] ![70 1][] Cl 青旅半醒/ 2022年05月20日 00:15/ 0 赞/ 182 阅读
相关 33_反射(类加载、反射)_讲义 今日内容介绍 1、类加载器 2、反射构造方法 3、反射成员变量 4、反射成员方法 5、反射配置文件运行类中的方法 01类加载器 ![在这里插入图片 淩亂°似流年/ 2022年03月27日 07:02/ 0 赞/ 258 阅读
还没有评论,来说两句吧...