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();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java面试题--JVM大厂篇之G1 GC的分区管理方式如何减少应用线程的影响

目录 引言: 正文: 1. 区域划分(Region) 2. 并行和并发回收 3. 区域优先回收(Garbage First) 4. 可预测的停顿时间 5. 分阶段回收 6. 复制和压缩 实际效果: 场景举例 1. 减少单次GC的影响 2. 支持高并发环境 3. 优…

数学建模(1):期末大乱炖

1 概述!! 1.1 原型和模型 原型:客观存在的研究对象称为原型,也称为“系统”、“过程”。 机械系统、电力系统、化学反应过程、生产销售过程等都是原型; 研究原型的结构和原理, 从而进行优化、预测、评价…

一区算法MPA|海洋捕食者算法原理及其代码实现(Matlab/Python))

Matlab/Python: 本文KAU将介绍一个2020年发表在1区期刊ESWA上的优化算法——海洋捕食者算法 (Marine Predators Algorithm,MPA)[1] 该算法由Faramarzi等于2020年提出,其灵感来源于海洋捕食者之间不同的觅食策略、最佳相遇概率策略、海洋记…

【MySQL】Linux下MySQL的目录结构、用户、权限与角色

一、Linux下MySQL的目录结构 1、MySQL相关目录 数据库文件存放路径:/var/lib/mysql数据库命令存放路径:/user/bin和/user/sbin配置文件目录:/usr/share/mysql-8.0/、/usr/share/mysql/和/etc/my.cnf 2、假设我们创建了一个数据库dbtest1&a…

使用evo工具比较ORB-SLAM3的运行轨迹(从安装到解决报错)

ORB-SLAM2和ORB-SLAM3怎么跑出来,之前都有相关的保姆级的教程,下来给大家介绍一款evo工具,给科研加速!!! 文章目录 1.下载evo2.生成轨迹3.evo别的功能使用 1.下载evo 输入命令下载 pip install -i https…

你真的会udf提权???数据库权限到系统权限 内网学习 mysql的udf提权操作 ??msf你会用了吗???

我们在已经取得了数据库的账号密码过后,我们要进一步进行提取的操作,我们mysql有4钟提权的操作。 udf提权(最常用的)mof提权启动项提权反弹shell提权操作 怎么获取密码操作: 怎么获取密码,通过sql注入获取这个大家都应该知道了&a…

百强韧劲,进击新局 2023年度中国医药工业百强系列榜单发布

2024年,经济工作坚持稳中求进、以进促稳、先立后破等工作要求。医药健康行业以不懈进取的“韧劲”,立身破局,迎变启新。通过创新和迭代应对不确定性,进化韧性力量,坚持高质量发展,把握新时代经济和社会给予…

零基础开始学习鸿蒙开发-读书app简单的设计与开发

目录 1.首页设计 2.发现页面的设计 3.设置页面的设计 4.导航页设计 5.总结: 6.最终的效果 1.首页设计 Entry Component export struct home {State message: string 首页build() {Row() {Column() {Text(this.message).fontSize(50).fontWeight(FontWeight.B…

基于线调频小波变换的非平稳信号分析方法(MATLAB)

信号处理领域学者为了改进小波变换在各时频区间能量聚集性不高的缺点,有学者在小波分析基础上引入调频算子构成了线性调频小波变换,线调频小波一方面继承了小波变换的理论完善性,另一方面用一个新的参数(线调频参数)刻…

构建高效业财一体化管理体系

构建高效业财一体化管理体系 业财一体化战略意义 提升决策质量 强化数据支撑:通过整合业务与财务数据,为决策提供准确、实时的信息基础,确保分析的深度与广度。促进业务与财务协同:打破信息孤岛,实现业务流程与财务管…

Django 定义模型执行迁移

1,创建应用 Test/app8 python manage.py startapp app8 2,注册应用 Test/Test/settings.py 3,配置路由 Test/Test/urls.py from django.contrib import admin from django.urls import path, includeurlpatterns [path(app8/, include(a…

Linux服务器上安装CUDA11.2和对应的cuDNN 8.4.0

一、检查 检查本机是否有CUDA工具包,输入nvcc -V: 如图所示,服务器上有CUDA,但版本为9.1.85,版本过低,因此博主要重装一个新的。 二、安装CUDA 1.查看服务器最高支持的CUDA版本 在命令行输入nvidia-smi查看显卡驱动…

Mining Engineering First Aid Riding

4个最主要的日常技能:Mining 采矿 Engineering 工程 First Aid 急救 Riding 骑术 4个最主要的日常技能

C# 信号量的使用

学习来源:《.net core 底层入门》 第六章第9节:信号量 案例:主线程负责添加数据,子线程负责获取数据 使用SemaphoreSlim(轻信号量)实现: using System; using System.Collections.Generic; us…

AI写作变现指南:从项目启动到精通

项目启动 1. 确定目标客户群体 首先,明确谁是我们的目标客户。以下是一些潜在的客户群体: 大学生:他们需要写论文、报告、演讲稿等。 职场人士:包括需要撰写商业计划书、市场分析报告、项目提案等的专业人士。 自媒体从业者&…

TiDB-从0到1-BR工具

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容 一、BR工具 BR工具全称backup & restore,如同MySQL可以通过mysqldump和xtrabackup进行备份…

入门JavaWeb之 JDBC 连接数据库

JDBC:Java Database Connectivity,Java 数据库连接 需要 jar 包支持: java.sql javax.sql mysql-connector-java(连接驱动,必须导入) 在 MySQL 先建个 jdbc 数据库后 USE jdbc; 执行后再 CREATE TABLE…

Java_日志

日志技术 可以将系统执行的信息,方便的记录到指定的位置(控制台、文件中、数据库中) 可以随时以开关的形式控制日志启停,无需侵入到源代码中去进行修改。 日志技术的体系结构 日志框架:JUL、Log4j、Logback、其他实现。 日志接口&#xf…

youlai-boot项目的学习(3) 本地redis、MinIO的安装与配置

youlai-boot项目除了使用mysql数据库、还有redis,以及OSS服务,OSS除了云OSS服务,还有自部署的MinIO服务。 前面我们已经安装好了mysql数据库,那么我们来看看本地redis、MinIO服务怎么部署 环境 mac OS, iterm2&#…

线性结构之栈结构

栈是一种只能从一端存取数据并且遵循“后进先出”原则的线性存储结构。这句话中体现了栈结构的三个特征——只能从一端存取数据,遵循“后进先出”的原则和线性存储结构。因此如果我们要实现一个栈结构的数据结构,就必须要满足这三点要求。提到线性结构&a…