Java之反射:Class类、调用构造方法、访问字段、访问方法

反射

什么是反射:

​ 反射是Java语法的一种高级特性,在“运行期间”对Java的类型信息进行检查,操作处理。例如:加载JDBC驱动类,Mybatis动态处理resultType,Spring根据配置创建Bean对象等使用场景都用反射实现

常见的反射操作:

  1. 获取Class类型信息
  2. 执行构造方法创建对象
  3. 调用实例方法
  4. 通过成员变量保存值和获取值

Class类

Class对象用于保存一个类的类型信息,它是反射的入口操作

获取Class对象的三种方式:

  1. 通过类名:

    Class cls = Book.class;
    
  2. 通过forName()方法:

    Class cls = Class.forName("com.dong.Book");
    
  3. 通过对象:

    Class cls = new Book().getClass();
    

类只加载一次,三个方法获取同一个类的Class对象,输出相同

Constructor类

代表一个类中的构造方法(构造器),用于创建“目标对象”

  • 获取Constructor构造方法的方式
  1. Class对象.getConstructor() 获取无参构造方法

    Class cls = Book.class;Constructor constructor1 = cls.getConstructor();  // 获取无参构造方法
    
  2. Class对象.getConstructor(Class…) 获取有参构造方法

    Class cls = Book.class;//	获取有参构造方法,在Book类中存在有参构造方法
    //	参数列表为:String,String,double,int
    Constructor constructor2 = cls.getConstructor(String.class,String.class,double.class,int.class);
    
  • 执行Constructor构造方法的方式
  1. Constructor对象.newInstance() 执行无参构造方法

    // 执行无参构造方法,创建目标对象
    Object obj = constructor1.newInstance();
    
  2. Constructor对象.newInstance(值…) 执行有参构造方法

    // 执行有参构造方法,创建目标对象
    Object obj = constructor2.newInstance("额尔古纳河右岸","迟子建",12.5,100);
    
  • 获取所有的构造方法

    Class<Book> cls = Book.class;
    Constructor[] constructors = cls.getConstructors();
    

总结:创建目标对象的方法(3种):

  1. 通过Class对象:

    Class<Book> cls = Book.class;
    Object obj = cls.newInstance();
    
  2. 通过无参构造方法

  3. 通过有参构造方法

Field类

代表一个类中的成员变量(字段),用于为“目标对象”保存值和获取值

  • 获取Field成员变量的方式
  1. 获取public修饰的成员变量:Class对象.getFields()

    Class cl = Book.getClass();
    Field[] fields = cl.getFields();
    
  2. 获取public/private修饰的成员变量:Class对象.getDeclaredFields()

    Class cl = Book.getClass();
    Field[] fields = cl.getDeclaredFields();
    
  • 使用Field成员变量的方式
  1. Class对象.getField(成员变量名称):public修饰的成员变量

    Class cl = Book.getClass();
    Field[] fields = cl.getFields("bookName");
    
  2. Class对象.getDeclaredField(成员变量名称):public\private修饰的成员变量

    Class cl = Book.getClass();
    Field[] fields = cl.getDeclaredFields("bookName");
    
  • 给Filed成员变量赋值:

    Field对象.set(目标对象,Value);

    // 获取需要创建的对象类型信息
    Class bookClass = Book.class;
    // 创建对象
    Object bookObj = bookClass.newInstance();
    // 获取该类型中bookName成员变量
    Field bookNameField = bookClass.getDeclaredField("bookName");// book对象.bookName = "舒克和贝塔"
    bookNameField.setAccessible(true);  
    // 由于Book类中bookName是私有的,所以需要设置
    bookNameField.set(bookObj, "舒克和贝塔");
    

    setAccessible:

    封装时,类的成员变量私有,将Field对象的accessible标志设置为ture表示:反射的对象在使用时应该取消 Java 语言访问检查;设置为false表示:反射的对象应该实施 Java 语言访问检查

  • 获取成员变量名称并获取变量值

    获取成员变量名称:Field对象.getName();

    获取变量值:Field对象.get(目标对象名);

    例:

    public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 获取类型的信息对象Class<Book> cls = Book.class;// 创建目标对象Constructor constructor = cls.getConstructor(String.class,String.class,double.class,int.class);Object obj = constructor.newInstance("额尔古纳河右岸","迟子建",12.6,100);show(obj);
    }public static void show(Object obj) {try {Class cl = obj.getClass(); Field[] fields = cl.getDeclaredFields();for(Field f  : fields) {f.setAccessible(true);System.out.println("属性"+f.getName());    // 获取成员变量属性System.out.println("属性值:"+f.get(obj));  // 获取变量属性值}} catch (SecurityException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}
    }
    

Method类

代表一个类中的方法,用于调用执行该方法

  • 获取Method方法的方式
  1. 获取指定名称和参数列表的Method:Class对象.getMethod(String name,Class…parameterTypes)

    在调用时,需要传入方法名,以及参数列表类型,eg:
    Class cls = Book.class;
    Method method = cls.getMethod("read",String.class,String.class);
    
  2. 获取所有的Method方法:Class对象.getMethods();

    Class cls = Book.class;
    Method[] methods = cls.getMethods();for(Method m : methods) {System.out.println(m);System.out.println("访问修饰符::"+m.getModifiers());   System.out.println("返回值类型:"+m.getReturnType());// 参数列表为一个Parameter类型的数组System.out.println("参数列表:");for(Parameter p : m.getParameters()) {System.out.println(p);}System.out.println("方法名称:"+m.getName());System.out.println();
    }
    
    • getModifiers():获取访问修饰符
    • getReturnType():获取返回值类型
    • getParameters():获取参数列表
    • getName():获取方法名称
  • 执行Method方法的方式

Method对象.invoke(目标对象,方法参数):

eg:读取配置文件调用方法

config.txt:

com.dong.Task
execute

Task类:

public class Task {public String execute(String id) {System.out.println("ִ执行流水号:" + id);System.out.println("ִ执行了Task任务类的excute方法!!!");return "ok";}
}

Job类:

public class Job {public String run(String id) {System.out.println("执行流水号:" + id);System.out.println("ִ执行了Job任务类的run方法!!!");return "success";}
}

Main方法:

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;public class reflex07 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 读取配置文件调用方法,修改配置文件中内容执行不同的方法List<String> configList = Files.readAllLines(Paths.get("f:\\config.txt"));String className=configList.get(0);String methodName=configList.get(1);// 获取类信息Class<?> cl = Class.forName(className);// 获取方法Method method = cl.getMethod(methodName, String.class);// 执行方法Object obj = cl.newInstance();  // 创建目标对象Object returnVal = method.invoke(obj, UUID.randomUUID().toString());  		// 调用方法System.out.println("返回值:"+returnVal);}
}

通过Method对象.invoke(目标对象,参数列表)调用方法

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

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

相关文章

CVE-2024-24565 CrateDB数据库任意文件读取漏洞

目录 前言 简介 ​编辑 环境搭建 漏洞复现 前言 本次介绍的漏洞不同与以往&#xff0c; 本次洞更多是适用于利用数据库提权。 利用数据库的导入导出数据的功能&#xff0c;我们往往可以将内部的一些敏感文件如/etc/passwd导入到数据库进行查看。也可以将数据导入到一些特…

SpringBoot + Thymeleaf打造VIP视频源解析网站

第一步&#xff1a;创建一个SpringBoot项目 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency><dependency><groupId>org.springframework.bo…

2024年刷题记录

马上要开始找实习了&#xff0c;又开始重启刷题计划了&#xff01;加油冲冲冲&#xff01;刷题的顺序follow代码随想录的60天刷题计划&#xff01;感谢FuCosmo的总结&#xff01;之前都是按照C的语法进行刷题的&#xff0c;这次也同样使用C。 Day 1 数组 这些题过年前都刷过了…

动态规划-背包问题进阶-完全背包和多重背包

我们之前讲过01背包&#xff0c;现在我们讲讲背包问题的进阶&#xff0c;先说完全背包。 完全背包相对于01背包的区别在于商店每个物品的无限性&#xff0c;就是可以被拿无数次&#xff0c;而01背包每个物品只能拿一次。 完全背包问题中&#xff0c;每个物品可以选择无限次&a…

【二叉树】遍历及构造

1. 定义 二叉树是一种树形数据结构&#xff0c;由节点组成&#xff0c;每个节点最多有两个子节点&#xff0c;分别为左子节点和右子节点。二叉树具有以下性质&#xff1a; 每个节点最多有两个子节点&#xff0c;称为左子节点和右子节点。 左子节点和右子节点可以为空&#xff0…

命令执行讲解和函数

命令执行漏洞简介 命令执行漏洞产生原因 应用未对用户输入做严格得检查过滤&#xff0c;导致用户输入得参数被当成命令来执行 命令执行漏洞的危害 1.继承Web服务程序的权限去执行系统命会或读写文件 2.反弹shell&#xff0c;获得目标服务器的权限 3.进一步内网渗透 远程代…

泛微e-office系统存在敏感信息泄露 附POC软件

免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该文章仅供学习用途使用。 1. 泛微e-office系统简介 微信公众号搜索:南风漏洞复…

mysql 锁详解

目录 前言 一、全局锁 二、表级锁 三、行锁 前言 为什么要设计锁&#xff0c;锁设计初衷是为了解决多线程下并发问题。出现并发的时候用锁进行数据同步&#xff0c;避免因并发造成了数据错误(数据覆盖)。可见锁的重要性&#xff0c;并不是所有的数据库都有锁。比如Redis&a…

什么是CODESYS开发系统

CODESYS是一种用于工业自动化领域的开发系统软件&#xff0c;提供了一个完整集成的开发环境。该软件由德国CODESYS GmbH&#xff08;原 3S-Smart Software Solutions GmbH&#xff09;公司开发&#xff0c;其最新版本为CODESYS V3。 CODESYS开发系统具有多种特性和优点。首先&a…

⭐北邮复试刷题105. 从前序与中序遍历序列构造二叉树__递归分治 (力扣每日一题)

105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,…

Rocky 8.9 Kubespray v2.24.0 在线部署 kubernetes v1.28.6 集群

文章目录 1. 简介2. 预备条件3. 基础配置3.1 配置hostname3.2 配置互信 4. 配置部署环境4.1 在线安装docker4.2 启动容器 kubespray4.3 编写 inventory.ini4.4 关闭防火墙、swap、selinux4.5 配置内核模块 5. 部署6. 集群检查 1. 简介 kubespray​ 是一个用于部署和管理 Kuber…

抽象方法与设计模式

抽象方法与设计模式 设计模式的六大原则工厂模式单例模式建造者模式过滤器模式装饰器模式享元模式责任链模式模板模式 真正的屎山不是初级程序员写的巨量胶水代码&#xff0c;而是没学明白抽象的程序员写的大量设计模式耦合形成的。你甚至不理解为什么当初的创作者需要使用到这…

基于postMessage和BroadcastChannel实现浏览器跨Tab窗口通信的方法介绍

文章目录 一、Broadcast Channel1、创建实例2、监听消息3、发送消息4、关闭5、示例演示5.1、主控页面5.2、受控页面 二、postMessage1、语法1.1、targetWindow1.2、message1.3、targetOrigin1.4、transfer&#xff08;可选的&#xff09; 2、示例演示2.1、parent页面2.2、child…

Elsevier投稿录用后的一些疑问

在elsevier投稿被录用之后&#xff0c;会收到好几个邮件&#xff1a; 第一封邮件是给你一个在线修改稿子的网站&#xff0c;让你核实作者&#xff0c;文献等等的信息&#xff0c;以及编辑做的修改&#xff0c;要注意的是有几个query问题是必须回答的。然后你在线修改完提交就可…

CF1468J Road Reform 题解

CF1468J Road Reform 题解 link CF1468J Road Reform 题面翻译 给定一个有 n n n 个节点&#xff0c; m m m 条无向带权边的图&#xff0c;和一个参数 k k k&#xff0c;第 i i i 条边权值为 s i s_i si​。 现在你要保留这个图中的 n − 1 n-1 n−1 条边使得这个图变…

java导出动态下拉框excel模板

1.原始模板 2.导出模板,下拉框为数据库中得到动态数据 public void downloadTemplate(HttpServletResponse response) throws IOException {// 所有部门List<String, String> departments expertManageMapper.selectAllDepartment();//所有职位List<String, String&g…

前端关于Vue跳转外部链接(百度为例)

一定要加这句 window.location.href http://www.baidu.com/s?wd this.wd;关于Vue跳转外部链接&#xff08;百度为例&#xff09;_vue3.2 点击按钮 router.resolve 跳转 百度-CSDN博客 <img src"./hd1.jpg" width"200px" height"100px" c…

模块 time:时间和日期处理

MicroPython内置模块 time&#xff1a;时间和日期处理 MicroPython的内置模块time是一个用于处理时间相关功能的模块&#xff0c;它实现了CPython模块的一个子集&#xff0c;但也有一些特殊的特点和限制。本文将从以下几个方面介绍time模块的主要特点、应用场景&#xff0c;以…

基于Java (spring-boot)的社区物业管理系统

一、项目介绍 本系统共分为两个角色&#xff1a;管理员和业主。 主要功能有&#xff0c;核心业务处理&#xff0c;基础信息管理&#xff0c;数据统计分析 核心业务处理&#xff1a;车位收费管理&#xff0c;物业收费管理&#xff0c;投诉信息管理&#xff0c;保修信息管理。 …

Top-N 泛型工具类

一、代码实现 public class TopNUtil<E extends Comparable<E>> {private final PriorityQueue<E> priorityQueue;private final int n;/*** 构造 Top-N*/public TopNUtil(int size) {if (size < 0) {throw new IllegalArgumentException("Top-N si…