Java基础学习(十八)

news/2025/2/23 21:39:00/文章来源:https://www.cnblogs.com/victoria6013/p/18732910

Java基础学习(十八):反射

目录
  • Java基础学习(十八):反射
    • 概念
    • 获取 class 对象
    • 反射获取构造方法
    • 反射获取成员变量
    • 反射获取成员方法

本文为个人学习记录,内容学习自 黑马程序员


概念

  • 反射允许对封装类的字段(成员变量)、方法(成员方法)和构造函数(构造方法)的信息进行编程访问
  • 作用:
    • 对于成员变量:获取修饰符,获取名字,获取类型,赋值/获取值
    • 对于成员方法:获取修饰符,获取名字,获取形参,获取返回值,获取抛出的异常,获取注解,运行方法
    • 对于构造方法:获取修饰符,获取名字,获取形参,创建对象
  • 示例:IDEA 在调用成员/变量方法或者填写构造方法的形参时出现的提示都是通过反射达成的

获取 class 对象

  • 在使用反射之前,需要先获取字节码文件对象,也即 Class 对象

  • 获取 class 对象有三种方式,这三种方式分别应用于 Java 中的三种阶段

    • Class.forName("全类名");
    • 类名.class;
    • 对象.getClass();
  • Java 的三种阶段:

    1. 源代码阶段:将 Java 文件编译成字节码文件,此时采用第一种获取 class 对象的方式
    2. 加载阶段:将字节码文件加载到内存中,此时采用第二种获取 class 对象的方式
    3. 运行阶段:在内存中运行代码,此时采用第三种获取 class 对象的方式
  • 示例:

    public class Test {public static void main(String[] args) throws ClassNotFoundException {// 方式一// 全类名 = 包名 + 类名Class clazz1 = Class.forName("com.victoria.demo.Student");// 方式二Class clazz2 = Student.class;// 方式三Student s = new Student();Class clazz3 = s.getClass();}
    }
    
  • 总结:一般使用第一种方式,只需要作为参数传递 class 对象时采用第二种方式,只有已经有对象时才使用第三种方式


反射获取构造方法

方法名 说明
Constructor<?>[] getConstructors() 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors() 返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes) 返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造方法对象

示例:

public class Test {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// 1.获取字节码文件对象Class clazz = Class.forName("com.victoria.demo.Student");// 2.使用不同方法获取构造方法// 1)获取全部的公共构造方法Constructor[] cons1 = clazz.getConstructors();for (Constructor c : cons1) {System.out.println(c);}// 2)获取全部的构造方法Constructor[] cons2 = clazz.getDeclaredConstructors();for (Constructor c : cons2) {System.out.println(c);}// 3)获取单个公共构造方法,输入参数需要和构造方法的形参一一对应// 例如要获取空参构造方法,输入参数就为空;要获取两个参数的构造方法,输入参数就为这两个参数类型的Class对象Constructor con1 = clazz.getConstructor();System.out.println(con1);Constructor con2 = clazz.getConstructor(String.class, int.class);System.out.println(con2);// 3.获取构造方法后,查看修饰符、名字、形参等信息int modifiers = con2.getModifiers();int count = con2.getParameterCount();// 4.获取构造方法后,创建对象// setAccessible()方法用于临时取消权限校验,用于让私有构造方法也能在此处创建对象con2.setAccessible(true);Student stu = (Student) con2.newInstance("a", 18);System.out.println(stu);}
}

反射获取成员变量

方法名 说明
Field[] getFields() 返回所有公共成员变量对象的数组
Field[] getDeclaredFields() 返回所有成员变量对象的数组
Field getField(String name) 返回单个公共成员变量对象
Field getDeclaredField(String name) 返回单个成员变量对象

示例:

public class Test {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {// 1.获取字节码文件对象Class clazz = Class.forName("com.victoria.demo.Student");// 2.使用不同方法获取成员变量// 1)获取全部的公共成员变量Field[] fields = clazz.getFields();for (Field field : fields) {System.out.println(field);}// 2)获取全部的成员变量Field[] declaredFields = clazz.getDeclaredFields();for (Field field : declaredFields) {System.out.println(field);}// 3)获取单个成员变量,输入参数为成员变量名Field name = clazz.getDeclaredField("name");System.out.println(name);// 3.获取成员变量后,查看修饰符、名字、数据类型等信息int modifiers = name.getModifiers();String n = name.getName();Class<?> type = name.getType();// 4.获取对象中成员变量记录的值Student s1 = new Student("a", 18);name.setAccessible(true);String value = (String) name.get(s1);// 5.修改对象中成员变量记录的值Student s2 = new Student("a", 18);name.setAccessible(true);name.set(s2, "b");}
}

反射获取成员方法

方法名 说明
Method[] getMethods() 返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes) 返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回单个成员方法对象

示例:

public class Test {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {// 1.获取字节码文件对象Class clazz = Class.forName("com.victoria.demo.Student");// 2.使用不同方法获取成员方法// 1)获取全部的公共成员方法Method[] methods = clazz.getMethods();for (Method method : methods) {System.out.println(method);}// 2)获取全部的成员方法Method[] declaredMethods = clazz.getDeclaredMethods();for (Method method : declaredMethods) {System.out.println(method);}// 3)获取单个成员方法,输入参数为成员方法名和其对应的形参Method method = clazz.getMethod("setName", String.class);System.out.println(method);// 3.获取成员方法后,查看修饰符、名字、形参、抛出的异常等信息int modifiers = method.getModifiers();String n = method.getName();int count = method.getParameterCount();Class<?>[] exceptionTypes = method.getExceptionTypes();// 4.运行方法// invoke()方法第一个参数表示方法的调用者,第二个参数为调用方法时传递的实际参数Student s = new Student();method.setAccessible(true);Object result = method.invoke(s, "aaa");System.out.println(result);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《痞子衡嵌入式半月刊》 第 118 期

痞子衡嵌入式半月刊: 第 118 期这里分享嵌入式领域有用有趣的项目/工具以及一些热点新闻,农历年分二十四节气,希望在每个交节之日准时发布一期。 本期刊是开源项目(GitHub: JayHeng/pzh-mcu-bi-weekly),欢迎提交 issue,投稿或推荐你知道的嵌入式那些事儿。 上期回顾 :《…

【牛客训练记录】牛客周赛 Round 82

训练情况赛后反思 C题没想明白,但是发现了数列一定是不增加的,另外第一次出现的数字,那个位置就必须是那个数字,剩下可能是乘法原理之类的东西吧,但是没做出来 A题 判断字符串第一位和最后一位是否一致即可点击查看代码 #include <bits/stdc++.h> // #define int lo…

【Atcoder训练记录】AtCoder Beginner Contest 394

训练情况赛后反思 没在赛时打的,只做了签到TAT A题 统计字符串中 2 的数量,最后去掉其他的,只输出 2点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;void solve(){string s; cin>>s;int ans = 0;for(int …

DPDK收发包梳理

DPDKeal初始化 内存管理:大页,内存池 驱动开启调试信息 make config T=x86_64-native-linuxapp-gcc export EXTRA_CFLAGS=-O0 -g3 -ggdb make -j8 dpdk通过makefile编译 meson + ninja没学过,太麻烦了,可以参考dpdk17的文档,里面有介绍make编译方式。 https://doc.dpdk.or…

空气流量和空气压力参数解耦系统simulink建模与仿真

1.课题概述空气流量和空气压力参数解耦系统simulink建模与仿真,在许多系统中,空气流量(Q)和压力(P)之间存在耦合关系,这意味着改变一个参数会影响到另一个参数。通过解耦系统解决这种问题,从而提高系统的控制稳定性。2.系统仿真结果 (完整程序运行后无水印)3.核心程序…

【库】Coravel Cache缓存

Coravel 通过使高级应用程序功能(如任务/作业调度、排队、缓存、邮件(以及更多!))易于访问且易于使用,帮助开发人员快速启动并运行 .NET 应用程序。具有简单、富有表现力和直接的语法。Coravel非常简单,通过Rember来保存缓存数据,同时可以设定缓存的时长,然后通过Get来…

4.优化器 - 模型评估

优化器 - optimizer优化器就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数损失函数(目标函数)值不断逼近全局最小优化器不计算梯度,他只是梯度的更新者,它决定了以什么样的形式更新参数如果损失函数是…

【软件开发】CMake学习笔记

【软件开发】CMake 学习笔记 CMake 是什么? 是构建系统(如 Visual Studio)的文件(如 .vcxproj .sln)的创建器,具体要生成的构建系统可以通过 CMakePresets 文件中的 generator 指定。 构建系统一般不是跨平台的,但 CMake 支持在不同的操作系统上生成不同的构建系统文件,…

Python糖尿病数据分析:深度学习、逻辑回归、K近邻、决策树、随机森林、支持向量机及模型优化训练评估选择

全文链接:https://tecdat.cn/?p=39864 原文出处:拓端数据部落公众号 分析师:Weilong Zhang 本研究旨在利用机器学习和深度学习模型对糖尿病数据进行分析和预测。通过对糖尿病数据集的读取、预处理、特征分析,运用多种机器学习算法如逻辑回归、K近邻、决策树、随机森林、支…

使用MyBatis框架时Mapper传参是否需要使用@Param注解

在使用MyBatis作为Java项目的ORM框架时,在Mapper接口中传递参数需要通过@Param注解指定参数名称,这样才能在Mapper接口对应的xml文件中引用到对应名称的参数。如果不在Mapper接口中明确使用@Param注解时将会报错:找不到指定名称的参数。 追根溯源,这要从MyBatis获取Mapper接…

关于在阿里云服务器上搭建简单的keepalived主备服务器时出现的问题

问题:在进行keepalived主备服务器配置时,仅配置了RID,状态,通讯端口,VRID,优先级,通告报文发送时间,密码认证部分,VIP。在启动服务时,发现两台设备均跳转状态为MASTER。原因:出现这问题的场景是在阿里VPS云服务器网络环境中,因为路由交换层禁用了ARP的广播限制,造…

子串分值

‌输入和初始化‌: 读取字符串 str,并从索引 1 开始存储(C++ 中字符串索引从 0 开始,但这里为了简化计算,从 1 开始)。 n 存储字符串的长度。 数组 l[i] 存储字符 str[i] 上一次出现的位置。 数组 r[i] 存储字符 str[i] 下一次出现的位置。 数组 p 用于临时存储每个字符最…