【JavaSE】反射机制-基础概述

news2025/1/22 9:05:28

Catalog

  • JavaSE-反射机制-基础概述
    • 1. 应用场景
    • 2. 优点
    • 3. 缺点
    • 4. Class类解析
    • 5. 获取Class类实例的方式
    • 6. 反射机制是什么
    • 7. 反射机制原理图(老韩)
    • 8. 具体应用

JavaSE-反射机制-基础概述

1. 应用场景

常见的如下:

  1. 当获取到一个未知类型但是知道其中的方法名方法参数的类对象时,可以通过反射机制调用这个方法,甚至于获取到这个类的具体信息。

  2. 通过配置文件动态加载类,动态调用类中的方法和属性。

2. 优点

  1. 动态加载:即使用到某个类时,才对这个类进行加载。

3. 缺点

  1. 使用反射的程序是基于解释执行的,影响程序执行速度。

4. Class类解析

了解反射机制,必须先了解Class类,Class实例是在类加载阶段完成的,即根据字节码文件,通过类加载器来实现Class类实例的加载(将字节码的二进制数据和Class类对象放入内存中)。

关于Class类,该类和普通类的主要区别在于

  • 该类是由系统创建。
  • 每一个普通的类都有一个对应的Class类实例,这个实例包括了普通类的字段、方法、构造函数。

Class类中常用的API

方法描述
getName()获取类的完整名称。
getSimpleName()获取类的简单名称,即去掉包名的类名。
getModifiers()获取类的修饰符,比如publicprivate等。
getFields()获取类的公共字段,包括超类的。
getDeclaredFields()获取类声明的所有字段,包括私有的。
getMethods()获取类的公共方法,包括超类的。
getDeclaredMethods()获取类声明的所有方法,包括私有的。
newInstance()创建类的一个新实例(已过时,不推荐使用)。
getConstructor(Class<?>... parameterTypes)获取指定参数类型的构造函数。
getDeclaredConstructor(Class<?>... parameterTypes)获取类声明的构造函数。

5. 获取Class类实例的方式

  1. 类名.class:通常用于传参。
  2. Class.forname(类的全路径名):在已知类的全路径名的前提下,多用于配置文件,读取类的全路径,加载类。
  3. 实例.getClass():通过对象直接获取Class类的实例。
  4. 对象.getClass().getClassLoader().loadClass(类的全路径名):通过类加载器获取Class类实例。
 /**
     * 获取Class实例的六种方式
     */
    @Test
    public void testGetClass() throws Exception{
        //编译期间--->通过调用静态方法forName()获取
        Class<?> cls = Class.forName(PATH_DOG);
        System.out.println(cls);

        //类加载阶段--->通过类名.class获取
        cls = Dog.class;
        System.out.println(cls);


        //运行阶段--->通过对象实例创建Class对象
        Object dog = cls.newInstance();
        System.out.println(dog.toString());
        Class<?> aClass = dog.getClass();
        System.out.println("运行阶段:" + aClass);

        //使用类加载器加载Class类的对象
        Class loadClass = dog.getClass().getClassLoader().loadClass("com.aimin.Dog");


        //基本数据类型
        Class<Integer> integerClass = int.class;
        Class<Character> characterClass = char.class;
        System.out.println(integerClass);
        System.out.println(characterClass);

        Class<Integer> integerClass1 = Integer.TYPE;
        Class<String> stringClass = String.class;
        Class<Character> characterClass1 = Character.TYPE;
        System.out.println(integerClass1);
        System.out.println(stringClass);
        System.out.println(characterClass1);


    }

6. 反射机制是什么

在类加载阶段结束之后,内存中会出现所加载类对应的Class类对象,这个Class类对象包含了所加载类的全部信息,就像一面镜子一样反射了所加载类的全部信息,通过Class类对象就可以操作所加载的全部属性和方法。

7. 反射机制原理图(老韩)

这个图是韩老师课程里面画的图,对类的加载描述地很清晰

Alt

8. 具体应用

  1. 操作类的方法:

    /**
     * 通过反射获取方法对象,并对方法对象进行操作
     */
    public class GetMethodTest {
    
        @Test
        public void getMethod() throws Exception{
            //获取Class类Boss实例
            Class bossCls = Class.forName("com.aimin.Boss");
    
            //获取对象实例
            Object o = bossCls.newInstance();
    
            //获取公有方法对象
            Method hi = bossCls.getMethod("hi", String.class);
    
            //赋值
            hi.invoke(o, "aimin");
    
            //获取私有方法对象
            Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
    
            //开启暴破
            say.setAccessible(true);
    
            //赋值并执行方法获取返回值
            //Object result = say.invoke(o, 1, "What's matter with you ?", 'a');
    
            //由于"say"方法也是静态方法,所以也可以不指定对象
            Object result = say.invoke(null, 1, "What's matter with you ?", 'a');
            System.out.println((String) result);
    
        }
    }
    
    class Monster {
    }
    
    class Boss {//类
        public int age;
        private static String name;
    
        public Boss() {//构造器
        }
    
        public Monster m1() {
            return new Monster();
        }
    
        private static String say(int n, String s, char c) {//静态方法
            return n + " " + s + " " + c;
        }
    
        public void hi(String s) {//普通 public 方法
    
            System.out.println("hi " + s);
        }
    }
    
  2. 操作类的属性:

    /**
     * 通过反射操作对象(一般类型为Object)的属性
     */
    public class OperationFieldTest {
    
        @Test
        public void operationField() throws Exception{
            //获取Class类对象
            Class stuCls = Class.forName("com.aimin.Student");
    
            //获取类实例
            Object stu = stuCls.newInstance();
    
            //通过属性名获取属性对象---公共字段
            Field age = stuCls.getField("age");
    
            //赋值
            age.set(stu, 22);
            System.out.println(age.get(stu));
    
            //通过属性名获取属性对象---私有静态字段
            //由于静态字段与类加载有关,即静态对象是所有类实例共用的,所以在赋值的时候可以不指定对象实例
            Field name = stuCls.getDeclaredField("name");
    
            //开启暴破
            name.setAccessible(true);
    
            //赋值
            //name.set(null, "aimin");
            name.set(stu, "WangBB");
            System.out.println(name.get(null));
    
        }
    
    
    }
    
    
    class Student {//类
        public int age;
        private static String name;
    
        public Student() {//构造器
        }
    
        public String toString() {
            return "Student [age=" + age + ", name=" + name + "]";
        }
    }
    
  3. 获取类实例

    /**
     * 通过反射获取类实例
     */
    public class NewInstanceTest {
    
        @Test
        public void getInstanceByClass() throws Exception{
    
            //获取User类Class类对象
            Class userCls = Class.forName("com.aimin.User");
    
            //通过公有无参构造器创建对象
            Object user01 = userCls.newInstance();
            System.out.println("公有无参构造器" + user01);
    
            //通过公有有参构造器创建对象
            Constructor constructor = userCls.getConstructor(String.class);
    
            Object aimin = constructor.newInstance("aimin");
    
            System.out.println("公有有参构造器" + aimin);
    
            //通过私有构造器创建对象
    
            //1. 获取到私有构造器
            Constructor declaredConstructor = userCls.getDeclaredConstructor(int.class, String.class);
    
            //2. 开启暴破,类四暴力破解,之后才能获取到私有构造器
            declaredConstructor.setAccessible(true);
            Object test = declaredConstructor.newInstance(1, "test");
            System.out.println(test);
    
    
        }
    }
    
    class User { //User 类
        private int age = 10;
        private String name = "韩顺平教育";
    
        public User() {//无参 public
        }
    
        public User(String name) {//public 的有参构造器
            this.name = name;
        }
    
        private User(int age, String name) {//private 有参构造器
            this.age = age;
            this.name = name;
        }
    
        public String toString() {
            return "User [age=" + age + ", name=" + name + "]";
        }
    }
    
    

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

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

相关文章

错误、调试和测试

在程序运行过程中&#xff0c;总会遇到各种各样的错误。 有的错误是程序编写有问题造成的&#xff0c;比如本来应该输出整数结果输出了字符串&#xff0c;这种错误我们通常称之为bug&#xff0c;bug是必须修复的。 有的错误是用户输入造成的&#xff0c;比如让用户输入email地…

万亿国债即将发行,普通人能分一杯羹吗?信任为何提前亮起红灯?

财政部最新公告揭示&#xff1a;《2024年国债发行计划》正式出炉&#xff0c;涵盖一系列长期至超长期限的国债&#xff0c;涵盖20年、30年及50年期限。这一消息瞬间点燃了市场的讨论热情&#xff0c;激发了民众对于国家债务投资的兴趣与疑虑。 一、超长国债&#xff0c;你准备好…

春秋云镜 CVE-2023-52064

靶标介绍&#xff1a; Wuzhicms v4.1.0 被发现存在一个 SQL 注入漏洞&#xff0c;该漏洞通过位于/core/admin/copyfrom.php 的 $keywords 参数触发。 开启靶场&#xff1a; 打开靶场链接&#xff0c;如上图所示 开始实验&#xff1a; 1、通过安装Wuzhicms的知后台登录链接&a…

【OceanBase诊断调优】—— 备份恢复如何定位 NFS 服务异常

当备份、归档出现异常时&#xff0c;我们应该首先排除备份介质、网络是否正常&#xff0c;本文讲述如何通过系统表和日志来定位 NFS 服务异常。 适用版本 OceanBase 数据库所有版本。 如何查看备份归档异常&#xff1f; 查看备份归档状态表&#xff0c;MAX_NEXT_TIME 应与当…

树莓派5安装使用

文章目录 树莓派&#xff08;Raspberry Pi&#xff09;一、树莓派1、介绍2、构造3、信息 二、系统搭建1、硬件准备2、烧录系统2.1、下载[烧录软件](https://www.raspberrypi.com/software/) Raspberry Pi Imager2.2、下载[镜像](https://www.raspberrypi.com/software/operatin…

GO语言核心30讲 实战与应用 (io包,bufio包,os包,网络服务,http,性能分析)

原站地址&#xff1a;Go语言核心36讲_Golang_Go语言-极客时间 一、io包中的接口和工具 1. strings.Builder、strings.Reader 和 bytes.Buffer 这些类型实现了 io 包的很多接口&#xff0c;目的是什么&#xff1f; 是为了提高不同程序实体之间的互操作性。 程序实体是指比如网…

给app引导页说goodbye吧,皮之不存,毛将焉附。

有几个原因导致大部分创业者选择不开发独立的移动应用程序&#xff08;App&#xff09;&#xff1a; 成本和资源&#xff1a;开发和维护一个独立的移动应用程序需要投入大量的时间、资金和人力资源。对于创业公司来说&#xff0c;他们可能没有足够的资源来支持这样的开发和维护…

jumpserver接入ldap

ldap部署 基本安装和人员导入 1.CentOS7安装配置OpenLDAP与phpLDAPadmin (koomu.cn) 2.https://koomu.cn/centos7-install-openldap-server-and-phpldapadmin/ https://senmer.github.io/zh/posts/tech/ldap/openldap%E5%AE%89%E8%A3%85%E5%92%8C%E4%BD%BF%E7%94%A8/#%e4%b8%…

【上海生物发酵展精选展商】三门峡市高瑞生物技术有限公司

三门峡市高瑞生物技术有限公司注册成立于2017年2月23日&#xff0c;经营范围是微生物培养基原材料制造、销售。2017年度因场地搬迁、异地重建&#xff0c;公司由“三门峡市高山生物制品有限公司”更名为“三门峡市高瑞生物技术有限公司”。 该公司具有20余年丰富经验的微生物培…

杨校老师项目之基于SpringBoot的驾校预约课程管理系统

1.获取代码&#xff1a; 有偿获取&#xff1a;mryang511688 2.技术栈 后端 SpringBoot MySQL MyBatis Redis 前端 html、css、Javascript、Jquery 3.开发环境 JDK1.8、Maven3.5.4、MySQL5.7、Redis5.0.5、IntelliJ IDEA 4.内置功能 Springboot的项目&#xff0c;代码简…

React渲染流程

在 React 渲染分为两个阶段&#xff0c;Render 和 Commit&#xff0c;Render 是修改 React 组件的状态&#xff0c;把需要更新的组件标记为待更新&#xff0c;在 Commit 阶段将待更新的组件进行渲染并最终更新到浏览器的 Dom 树中。 Render 阶段是可以并执行操作的&#xff0c…

创龙教仪联合武汉纺织大学机械工程与自动化学院DSP实验室建设案例

原文链接&#xff1a;http://985.so/9n8h7 1►院校简介 西安邮电大学是一所以工为主&#xff0c;以信息科学技术为特色&#xff0c;工、管、理、经、文、法、艺多学科协调发展的普通高等学校&#xff0c;是我国特别是西北地区信息产业和现代邮政业人才培养、科学研究的重要基地…

Alembic 的使用(配合一款免费云数据库MemfireDB)

已经使用 Go 开发好一段时间了&#xff0c;最近因为工作原因又重操旧业搞起了 Python&#xff0c;基于 FastAPI 进行接口开发&#xff0c;然后去找了一下相关的脚手架&#xff0c;发现这其中挺多都用到了 Alembic&#xff0c;之前没使用过&#xff0c;于是学习了一下&#xff0…

MySQL创建存储过程函数(2)

DDL CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT COMMENT 学号,createDate datetime DEFAULT NULL,userName varchar(20) DEFAULT NULL,pwd varchar(36) DEFAULT NULL,phone varchar(11) DEFAULT NULL,age tinyint(3) DEFAULT NULL,sex char(2) DEFAULT NULL,i…

STM32时钟系统和时钟树

目录 STM32时钟系统 认识时钟树 什么是时钟 认识时钟树(F407) 配置系统时钟 系统时钟配置步骤 外设时钟使能和失能 sys_stm32_clock_init函数(F4) 时钟配置一般步骤 System文件夹_时钟系统工作原理 System文件夹介绍 Sys文件介绍 Delay文件介绍 Systic工作原理 S…

Ps 滤镜:干画笔

Ps菜单&#xff1a;滤镜/滤镜库/艺术效果/干画笔 Filter Gallery/Artistic/Dry Brush 干画笔 Dry Brush滤镜用于模拟使用干画笔技术&#xff08;介于油彩和水彩之间&#xff09;绘制的效果。此滤镜特别适用于为图像添加粗糙而富有表现力的笔触效果&#xff0c;同时减少细节&…

计算机发展史故事【17】

任天堂崛起 七十年代美国雅达利公司开创一个高科技的电脑游戏业。无独有偶&#xff0c;一家专营电脑游戏机的日本任天堂公司&#xff0c;自八十年代初期把它的家庭电脑游戏机&#xff08;FC&#xff09;投放市场后&#xff0c;不平静的世界被再一次激起轩然大波。这个小小的日本…

测缝计测量的是实际缝宽吗?

在土木工程中&#xff0c;测缝计作为一种重要的监测工具&#xff0c;广泛应用于桥梁、隧道、大坝等大型结构中&#xff0c;用以测量和监控结构接缝或裂缝的实际宽度变化。然而&#xff0c;有些人可能会产生疑问&#xff1a;测缝计测量的是实际缝宽吗?本文将对这一问题进行深入…

Linux基础之进程的优先级

目录 一、进程优先级的概念 二、进程优先级的查看 三、怎么修改进程优先级 四、进程饥饿 一、进程优先级的概念 cpu资源分配的先后顺序&#xff0c;就是指进程的优先权&#xff08;priority&#xff09;。优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linu…

5W 3KVAC隔离 宽电压输入 AC/DC 电源模块——TP05AL系列

TP05AL系列产品是一款经济型开板式开关电源&#xff0c;输出功率为5W&#xff0c;具有可靠性高、小体积、性价比高等特点&#xff0c;广泛用于工控和电力仪器、仪表、智能家居等相关行业。