java笔记(30)——反射的 API 及其 使用

文章目录

  • 反射
    • 1. 什么是反射
    • 2. 获取class字段(字节码文件对象)
        • 方式1
        • 方式2
        • 方式3
        • 应用
    • 3. 获取构造方法和权限修饰符
        • 前期准备
        • 获取所有的公共构造方法
        • 获取所有的构造方法
        • 获取无参构造方法
        • 获取一个参数的构造方法
        • 获取一个参数的构造方法
        • 获取两个参数的构造方法
          • 获取权限修饰符
          • 获取参数的个数
          • 获取构造方法中的所有参数
          • 使用反射创建对象(暴力反射)
    • 4. 获取成员变量
        • 前期准备
        • 获取公共成员变量
        • 获取所有的成员变量
        • 获取单个的成员变量
        • 获取私有的单个成员变量
          • 获取权限修饰符
          • 获取成员变量名
          • 获取成员变量的数据类型
          • 获取成员变量记录的值
          • 修改对象里面记录的值
    • 5. 获取成员方法
        • 前期准备
        • 获取类里面所有的方法对象(包含父类中所有的公共方法)
        • 获取类里面所有的方法对象(没有父类方法,但有本类中的私有方法)
        • 获取类中的单个公共方法
        • 获取类中的单个私有方法
          • 获取方法的修饰符
          • 获取方法的名字
        • 获取方法的形参个数
        • 获取方法的所有形参
        • 获取方法抛出的异常
        • 运行获取的方法
    • 6. 反射的使用
        • 获取对象信息并写入文件中

反射

1. 什么是反射

  1. 获取class对象
  2. 获取成员变量、构造方法、成员方法
  3. 获取各个关键字信息

pkcMwUe.md.png

2. 获取class字段(字节码文件对象)

方式1

Class.forName(“全类名”)

注意:此方法在源代码阶段,java文件编译成class文件的时候使用

方式2

类名.class

注意:此方法在加载阶段,运行代码前需要将class文件加载进入内存的时候

方式3

对象.getClass();

注意:此方法在程序的运行阶段使用

应用
package com.itchen.reflect;public class MyReflectDemo1 {public static void main(String[] args) throws ClassNotFoundException {Class clazz = Class.forName("com.itchen.reflect.Student");System.out.println(clazz);Class clazz2 = Student.class;System.out.println(clazz.equals(clazz2));Student s = new Student();Class clazz3 = s.getClass();System.out.println(clazz2.equals(clazz3));}
}

3. 获取构造方法和权限修饰符

前期准备
// 获取class对象
Class clazz = Class.forName("com.itchen.reflect.Student");
获取所有的公共构造方法
// 获取所有的公共构造方法
Constructor[] cons1 = clazz.getConstructors();
for(Constructor cos:cons1){System.out.println(cos);
}
获取所有的构造方法
// 获取所有的构造方法
Constructor[] cons2 = clazz.getDeclaredConstructors();
for (Constructor constructor : cons2) {System.out.println(constructor);
}
获取无参构造方法
// 获取无参构造方法
Constructor con1 = clazz.getDeclaredConstructor();
System.out.println(con1);
获取一个参数的构造方法
Constructor con2 = clazz.getDeclaredConstructor(String.class);
System.out.println(con2);
获取一个参数的构造方法
Constructor con3 = clazz.getDeclaredConstructor(int.class);
System.out.println(con3);
获取两个参数的构造方法
Constructor con4 = clazz.getDeclaredConstructor(String.class,int.class);
System.out.println(con4);
获取权限修饰符
int modifiers = con4.getModifiers();
System.out.println("权限修饰符字段为:"+modifiers);
获取参数的个数
int count = con4.getParameterCount();
System.out.println("参数个数为:"+count);
获取构造方法中的所有参数
Parameter[] parameters = con4.getParameters();
for (Parameter parameter : parameters) {System.out.println(parameter);
}
使用反射创建对象(暴力反射)
con4.setAccessible(true);    // 临时取消权限校验
Student stu = (Student)con4.newInstance("张三", 24);
System.out.println(stu);

4. 获取成员变量

前期准备
// 获取class对象
Class clazz = Class.forName("com.itchen.reflect.Student");
获取公共成员变量
// 获取公共成员变量
Field[] fields = clazz.getFields();
for (Field field : fields) {System.out.println(field);
}
获取所有的成员变量
// 获取所有的成员变量
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {System.out.println(field);
}
获取单个的成员变量
Field gender = clazz.getField("gender");
System.out.println(gender);
获取私有的单个成员变量
Field name = clazz.getDeclaredField("name");
System.out.println(name);
获取权限修饰符
int modifiers = name.getModifiers();
System.out.println("此成员变量的权限修饰符为:"+modifiers);
获取成员变量名
String name1 = name.getName();
System.out.println("此成员变量的名字为:"+name1);
获取成员变量的数据类型
Class type = name.getType();
System.out.println("成员变量的类型为:"+type);
获取成员变量记录的值
name.setAccessible(true);// 临时取消访问权限
Student s = new Student("张三",32,"m");
String value = (String) name.get(s);
System.out.println(value);
修改对象里面记录的值
name.set(s,"李四");
System.out.println(s);

5. 获取成员方法

前期准备
// 获取class对象
Class clazz = Class.forName("com.itchen.reflect.Student");
获取类里面所有的方法对象(包含父类中所有的公共方法)
Method[] methods = clazz.getMethods();
for (Method method : methods) {System.out.println(method);
}
获取类里面所有的方法对象(没有父类方法,但有本类中的私有方法)
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {System.out.println(method);
}
获取类中的单个公共方法
Method m1 = clazz.getMethod("eat", String.class);
System.out.println(m1);
获取类中的单个私有方法
Method m2 = clazz.getDeclaredMethod("eat", String.class);
System.out.println(m2);
获取方法的修饰符
int modifiers = m2.getModifiers();
System.out.println("此方法的权限修饰符为"+modifiers);
获取方法的名字
String name = m2.getName();
System.out.println("此方法的名字是:"+name);
获取方法的形参个数
int count = m2.getParameterCount();
System.out.println("此方法的形参个数:"+count);
获取方法的所有形参
Parameter[] parameters = m2.getParameters();
for (Parameter parameter : parameters) {System.out.println(parameter);
}
获取方法抛出的异常
Class[] exceptionTypes = m2.getExceptionTypes();
for (Class exceptionType : exceptionTypes) {System.out.println(exceptionType);
}
运行获取的方法
Student s = new Student();
m2.setAccessible(true);
/*** 1. 方法的调用者* 2. 方法调用时传递的实际参数* */
m2.invoke(s,"薯条");

6. 反射的使用

获取对象信息并写入文件中
// Java文件(有业务逻辑)
package com.itchen.reflectTest;import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;public class MyReflectDemo {public static void main(String[] args) throws IllegalAccessException, IOException {Student s = new Student("xA",23,'w',167.5,"睡觉");Teacher t = new Teacher("Bn",1000);saveObject(t);}public static void saveObject(Object obj) throws IllegalAccessException, IOException {// 1. 获取字节码文件对象Class clazz = obj.getClass();// 2. 创建io流BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\icyler\\Desktop\\AndroidProject\\shiyan\\mydynamicproxy\\a.txt"));// 3. 获取所有的成员变量Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {field.setAccessible(true);// 获取成员变量的名字String name = field.getName();// 获取成员变量的值Object value = field.get(obj);bw.write(name + " = " + value);bw.newLine();}// 4. 关闭io流bw.close();}
}

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

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

相关文章

【日常记录】【JS】SSE 流式传输 ChatGPT 的网络传输模式

文章目录 1、SSE 流式传输2、后端代码3、前端代码5、SSE和WS 对比6、chatgpt SSE的服务端返回的数据参考链接 单工通信是一种单向的通信方式,其中信息只能从发送端传输到接收端,而接收端不能向发送端发送任何信息。在Web开发中,Server-Sent E…

FL Studio 21 中文版分享(内含破解补丁)不是标题党

不知道为什么现在钓鱼的这么多(有答案的请在评论区上告诉我),就一个学习版的编曲软件有必要这样子搞吗?我也是在各类博客上找了一大堆教程,根本没几个能用的,索性直接到兔八哥爱分享上找了一个,…

C程序设计谭浩强第五版

程序习题 第一章1、第5题2、第6题 第三章1、第2题2、第2题3、第3题4、第4题Tips 第一章 1、第5题 编写一个C程序,运行时输出以下图形: #include <stdio.h> int main() {for (int i 0; i < 4; i) // 输出4行循环控制{for (int j 0; j < i; j) //第几行就输出几…

【TB作品】玩具电子琴,ATMEGA128单片机,Proteus仿真

题目 7 &#xff1a;玩具电子琴 基于单片机设计一能够发出中音八个音阶的音乐信号的电子琴&#xff0c;能够实现弹奏和音符显示功 能。 具有 8 个音阶按键&#xff0c;每按下一个按键时&#xff0c;所对应的 LED 点亮&#xff0c;音符进行显示。 具体要求如下&#xff1a; &…

PV操作经典例题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文☀️☀️☀️1.水果问题2.和尚打水问题3.餐厅职员问题4.汽车站点问题5.观察者-报告者问题6..阅览室问题 …

DEBOPIE框架:打造最好的ChatGPT交易机器人

本文介绍了如何利用 DEBOPIE 框架并基于 ChatGPT 创建高效交易机器人&#xff0c;并强调了在使用 AI 辅助交易时需要注意的限制以及操作步骤。原文: Build the Best ChatGPT Trading Bots with my “DEBOPIE” Framework 如今有大量文章介绍如何通过 ChatGPT 帮助决定如何以及在…

win10修改远程桌面端口,Windows 10下修改远程桌面端口及服务器关闭445端口的操作指南

Windows 10下修改远程桌面端口及服务器关闭445端口的操作指南 一、修改Windows 10远程桌面端口 在Windows 10系统中&#xff0c;远程桌面连接默认使用3389端口。为了安全起见&#xff0c;建议修改此端口以减少潜在的安全风险。以下是修改远程桌面端口的步骤&#xff1a; 1. 打…

任务调度器——任务切换

一、开启任务调度器 函数原型&#xff1a; void vTaskStartScheduler( void ) 作用&#xff1a;用于启动任务调度器&#xff0c;任务调度器启动后&#xff0c; FreeRTOS 便会开始进行任务调度 内部实现机制&#xff08;以动态创建为例&#xff09;&#xff1a; &#xff0…

web学习笔记(七十二)

目录 1.vue2通过$parent实现组件传值——父传子 2.vue2 通过$children实现组件传值——子传父 3. provide和inject传值&#xff08;依赖注入&#xff09; 4.vue2如何操作dom 5.vue2如何拿到最新的dom 6.filters过滤器 7.vue2的生命周期 8.vuex的用法 1.vue2通过$parent…

LLDP 基本原理

LLDP 简介 定义 LLDP&#xff08;Link Layer Discovery Protocol&#xff0c;链路层发现协议&#xff09;是 IEEE 802.1ab 中定义的第二层发现&#xff08;Layer 2 Discovery&#xff09;协议。 LLDP 提供了一种标准的链路层发现方式&#xff0c;可以将本端设备的主要能力、…

Wp-scan一键扫描wordpress网页(KALI工具系列三十二)

目录 1、KALI LINUX 简介 2、Wp-scan工具简介 3、信息收集 3.1 目标IP&#xff08;服务器) 3.2kali的IP 4、操作实例 4.1 基本扫描 4.2 扫描已知漏洞 4.3 扫描目标主题 4.4 列出用户 4.5 输出扫描文件 4.6 输出详细结果 5、总结 1、KALI LINUX 简介 Kali Linux 是一…

决策树划分属性依据

划分依据 基尼系数基尼系数的应用信息熵信息增益信息增益的使用信息增益准则的局限性 最近在学习项目的时候经常用到随机森林&#xff0c;所以对决策树进行探索学习。 基尼系数 基尼系数用来判断不确定性或不纯度&#xff0c;数值范围在0~0.5之间&#xff0c;数值越低&#x…

shark云原生-日志管理体系-filebeat

文章目录 1. deploy 文件1.1 RBAC1.2. DaemonSet1.2.1. Elasticsearch 连接信息1.2.2. Volume 1.3. ConfigMap1.3.1. 日志收集路径1.3.2. 日志事件输出目标 2. 在控制平面节点上运行Filebeat3. 查看输出3.1. 关于处理器 processors 4. 日志收集配置4.1. 手动指定日志收集路径4.…

简单多状态DP问题

这里写目录标题 什么是多状态DP解决多状态DP问题应该怎么做&#xff1f;关于多状态DP问题的几道题1.按摩师2.打家劫舍Ⅱ3.删除并获得点数4.粉刷房子5.买卖股票的最佳时期含手冷冻期 总结 什么是多状态DP 多状态动态规划&#xff08;Multi-State Dynamic Programming, Multi-St…

数据结构-顺序表的插入排序

顺序表的排序可以看作数组排序的拓展。基本逻辑和数组排序的逻辑大同小异。 由于顺序表中可以存放不同种的数据类型&#xff0c;进而和结构体排序又有相似之处。其中要注意的是&#xff08;->&#xff09;和&#xff08;.&#xff09;的区别。 -> 符号是针对指针进行的操…

实现了Map接口的HashMap

HashMap 底层主要由以下几个部分组成&#xff1a; 数组 (Node<K,V>[] table): 这是一个数组&#xff0c;存储的是链表的头节点。默认大小为 16。链表 (Linked List): 当发生哈希冲突时&#xff0c;即不同的键具有相同的哈希值&#xff0c;HashMap 使用链表来解决冲突。链…

计网之IP

IP IP基本认识 不使用NAT时&#xff0c;源IP地址和目的IP地址不变&#xff0c;只要源MAC和目的MAC地址在变化 IP地址 D类是组播地址&#xff0c;E类是保留地址 无分类地址CIDR 解决直接分类的B类65536太多&#xff0c;C类256太少a.b.c.d/x的前x位属于网路号&#xff0c;剩…

分治精炼宝库-----快速排序运用(⌯꒪꒫꒪)੭

目录 一.基本概念: 一.颜色分类&#xff1a; 二.排序数组&#xff1a; 三.数组中的第k个最大元素&#xff1a; 解法一&#xff1a;快速选择算法 解法二&#xff1a;简单粗暴优先级队列 四.库存管理Ⅲ&#xff1a; 解法一&#xff1a;快速选择 解法二&#xff1a;简单粗…

Github 2024-06-21 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-06-21统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目3Python项目3Java项目2非开发语言项目2JavaScript项目1Rust项目1Dart项目1HTML项目1Vue项目1C++项目1TensorFlow: 机器学习的开源…

【Linux】IO多路复用——select,poll,epoll的概念和使用,三种模型的特点和优缺点,epoll的工作模式

文章目录 Linux多路复用1. select1.1 select的概念1.2 select的函数使用1.3 select的优缺点 2. poll2.1 poll的概念2.2 poll的函数使用2.3 poll的优缺点 3. epoll3.1 epoll的概念3.2 epoll的函数使用3.3 epoll的优点3.4 epoll工作模式 Linux多路复用 IO多路复用是一种操作系统的…