Java反射-反射API、类加载过程

news2024/10/6 1:39:58

反射

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类加载过程

在这里插入图片描述

Java类加载主要分为这么几个阶段

  • 编译阶段

将.java源文件编译成.class字节码文件。

  • 运行阶段
  1. 当JVM第一次加载某一个用到的类时,会使用ClassLoader类加载器加.class文件加载到内存中。
  2. 连接-验证阶段:对class进行验证 头文件元数据等。
  3. 连接-准备阶段:收集字节码中的静态属性与静态代码块,并把静态属性赋值默认值。
  4. 连接-解析阶段:解析阶段主要是把符号引用转换为地址应用。
  5. 初始化:初始化阶段主要是运行class的静态代码块内容。

所有阶段都运行完成之后,此时JVM会把二进制的class文件加载到方法区,同时创建一个Class对象放入堆区。这个时候仅仅是完成了类的加载过程,之后才是创建对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/748273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3D 目标检测 SFD 问题记录

问题1&#xff1a;read timeout 顺着网址手动下载&#xff0c;然后放入相应的目录下 问题2&#xff1a;SparseModule import spconv 要改写成 import spconv.pytorch as spconv 问题3&#xff1a;skimage pip install scikit-image -i https://pypi.tuna.tsinghua.edu.cn/si…

MySQL备份、索引、视图

目录 一、备份 案例素材 1、使用mysqldump命令备份数据库中的所有表​编辑 2、备份booksDB数据库中的books表 ​3、使用mysqldump备份booksDB和test数据库 ​4、使用mysqldump备份服务器中的所有数据库 ​5、使用mysql命令还原第二题导出的books表 ​6、进入数据库使用…

cuda 线程索引ID的计算公式(图文)

博客中有一部分公式来自&#xff1a;cuda 线程索引ID的计算公式_blockidx.x_奕星星奕的博客-CSDN博客 我做的工作就是加了图更加形象的表示&#xff0c;还有公式的延申。 线程索引的计算公式 一个Grid可以包含多个Blocks&#xff0c;Blocks的组织方式可以是一维的&#xff0c;…

springboot人脸识别基于java的游戏推荐管理平台的设计及实现_0816qvue

表名&#xff1a;messages 功能&#xff1a;留言板 字段名称 类型 长度 字段说明 主键 默认值 id bigint 主键 主键 addtime timestamp 创建时间 CURRENT_TIMESTAMP userid bigint 留言人id username v…

数据结构--绪论

这里写目录标题 前言数据结构研究内容基本概念与术语数据元素与数据对象的区别数据结构逻辑结构存储结构 数据类型和抽象数据类型数据类型抽象数据类型定义格式举例 小结研究内容基础概念 抽象数据类型的表示和实现 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录…

什么是团体标准?

团体标准是由一个特定的组织、团体或行业共同制定的标准。它是一种在特定领域或行业中被广泛认可和采用的标准化文件&#xff0c;旨在规范产品、服务或流程的要求和规范。团体标准通常由行业协会、标准化组织或特定领域的专业团体开发&#xff0c;并经过广泛讨论、协商和验证&a…

【分享】报告!发现一个低代码数据可视化开发平台~

前言&#xff1a; 哈喽&#xff0c;大家好&#xff0c;我是木易巷~ 最近木易巷发现了一个低代码数据可视化开发平台&#xff0c;快来看看吧~ 1、介绍 GoView 是一个拖拽式低代码数据可视化开发平台&#xff0c;旨在帮助用户快速构建数据大屏&#xff0c;同时减少心智负担。通…

【沈阳航空航天大学808】22年真题及解析

哈喽大家好&#xff0c;鉴于真题系列反馈很不错&#xff0c;我决定重启真题系列&#xff01; 今天分享的是沈阳航空航天大学808信号与系统的试题及解析。本套试题难度中等&#xff0c;题量不多&#xff0c;相关计算复杂程度不大&#xff0c;考察了状态方程以及电路模型和稳态响…

token的验证流程

前端 后台 1.1 登录接口(携带账号和密码(MD5)) -->到后台 需要&#xff1a; 验证(账号密码)生成Token(包含id昵称&#xff0c;不敏感的数据) 1.2 后台需要解析&#xff0c;-->然后在前端显示 解析(解析出前端需要显示的数据)把token放到某一个位置…

2023年Unity面试题大全,共十万字面试题总结【收藏一篇足够面试,持续更新】

&#x1f388;前言 为了方便大家可以重点复习某个模块&#xff0c;所以将各方面的知识点进行了拆分并更新整理了新的内容&#xff0c;并对之前的版本中有些模糊的地方进行了纠正。此篇文章为Unity所有面试题模块的目录导航文章&#xff0c;全网最全的 Unity 面试题 都在这里了…

6.2.7 简单邮件传送协议SMTP

6.2.7 简单邮件传送协议SMTP 我们从一个SMTP发送的示例来了解简单邮件传送协议SMTP。 例&#xff1a;在主机Alpha.ARPA上的Smith发送邮件给在主机Beta.ARPA 的Jones.Green和Brown的过程。这里我们假定主机Alpha直接联系主机Beta。 Sender-SMTP和Receiver-SMTP建立了传输信道…

Hive(27): join连接查询

1 join概念回顾 根据数据库的三范式设计要求和日常工作习惯来说,我们通常不会设计一张大表把所有类型的数据都放在一起,而是不同类型的数据设计不同的表存储。比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关…

FreeSwitch 1.10.9 在CentOS7.9编译spandsp,V18_MODE_5BIT_4545错误

最近FreeSwitch 1.10.9 在CentOS7.9编译mod_spandsp出问题, making all mod_spandsp make[4]: Entering directory /usr/local/src/freeswitch-1.10.9.-release/src/mod/applications/mod_spandspCC mod_spandsp_la-mod_spandsp.loCC mod_spandsp_la-udptl.loCC …

【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性

目录 一、分布式锁实现原理二、不同的分布式锁实现方案三、Redis 的 setnx 实现互斥锁四、基于 Redis 实现分布式锁初级版五、误删锁问题&#xff08;业务阻塞导致&#xff09;六、误删锁&#xff08;Redis 命令原子性导致&#xff09;(1) Lua 脚本(2) Redis 编写和执行 Lua 脚…

VSCode LSP 语言服务器协议总结

为什么使用语言服务器协议&#xff1f; LSP(Language Server Protocol)语言服务器是一种特殊的 Visual Studio Code 扩展&#xff0c;可为许多编程语言提供编辑体验。使用语言服务器&#xff0c;您可以实现自动完成、错误检查&#xff08;诊断&#xff09;、跳转到定义以及VS …

python绘制二维直方图

文章目录 histscatterhist2d histscatter 如果想描述二维数据的分布特征&#xff0c;那么一个直方图显然是不够用的&#xff0c;为此可使用两个直方图分别代表x和y方向上的分布情况&#xff0c;同时透过散点图查看其整体的分布特征。 下面创建一组二元高斯分布的数据&#xf…

Nature揭秘:足量提供这个营养素可激活免疫细胞对抗肿瘤

圣犹太儿童研究医院&#xff08;St. Jude Childrens Research Hospital&#xff09;的科学家们发现&#xff0c;免疫细胞和肿瘤细胞在它们的局部环境中争会夺谷氨酰胺。谷氨酰胺是一种营养物质&#xff0c;对抗癌活性具有重要意义。如果癌细胞垄断谷氨酰胺&#xff0c;则可以阻…

2023年7月广州/东莞/深圳传统行业产品经理NPDP认证招生

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

单例模式:懒汉式和饿汉式

目录 懒汉模式和饿汉模式 区别 示例 懒汉模式线程不安全 懒汉模式线程安全 懒汉模式内部静态变量线程安全 饿汉式线程安全 指的是在系统生命周期内&#xff0c;只产生一个实例。 懒汉模式和饿汉模式 分为懒汉式和饿汉式 区别 创建时机和线程安全 线程安全&#xff1…

密码学入门——单向散列函数

文章目录 参考书一、简介二、术语介绍三、散列函数的应用四、单向散列函数的具体例子 参考书 图解密码技术&#xff0c;第三版 一、简介 单向散列函数&#xff08;One-way Hash Function&#xff09;是一种将任意长度的输入数据映射为固定长度输出的函数。该函数通常被用于密…