Java反射

用来动态的操纵Java代码

反射机制的主要作用:

  • 在运行时分析类的能力
  • 在运行时查看对象
  • 实现通用的数组操作代码
  • 利用Method对象

Class类

在Java程序运行时,系统为所有的对象维护一个被称为 运行时类型标识。这个标识存放了一个类运行时的类型信息。在编译时, 一个类对应一个Class对象,相同类型的对个实例对象会对应同一个Class对象。

获得Class类型实例的三种方式

  • 实例对象.getClass()
  • Class.forName(“类名”) //类名应该包含其包的路径
  • 类.class

注意:Class对象实际上表示的是一种类型,并不仅仅指类。int不是类,但int.class是一个Class类的对象
基本类型有Class对象,数组有Class对象,连关键字void也有Class对象
可以说Class类是对类型的抽象和集合

newInstance()

可以动态地创建一个类的实例

对象.getClass().newInstance()

newInstance()方法会调用默认的构造函数,如果没有默认构造函数则会抛出异常
如果想使用带参构造函数,需要用到Constructor类的newInstance方法,Constructor对象可以使用Class的实例获取,在下面讲

利用反射分析类的能力

主要是用java.lang.reflect包中的三个类,分别用于描述类的域、方法、构造器

  • Field
  • Method
  • Constructor

Field类

int getModifiers()      //获取修饰限定符的编号,使用Modifier.toString()静态方法将编号装换为对应字符串
Class getType()         //获取域的类型
String getName()        //获取域的名称

Method类

int getModifiers()      //获取修饰限定符的编号
Class getReturnType()       //获取返回值类型对象
String getName()        //获得方法的名称
Class[] getParameterTypes() //获得参数类型对象数组

Constructor类

int getModifiers()      //获取修饰限定符的编号
String getName()        //获得构造函数的名称
Class[] getParameterTypes() //获得参数类型对象数组

三种类对象的获取

使用Class类中的方法获得Field类、Method类、Constructor类

Field[] getFields()               //获取本类和父类的全部公有域
Method[] getMethods()                 //获取本类和从父类继承的全部公有方法
Constructor[] getConstructors()           //获取类中的全部公有构造函数
Field[] getDeclaredFields()           //获取类中的全部域,不包括父类的
Method[] getDeclaredMethods()             //获取类中的全部方法,不包括父类的
Constructor[] getDeclaredConstructors()       //获取类中的全部构造函数,不包括父类的

在运行时使用反射分析对象

可以使用反射机制进一步查看数据域的实际内容。

查看数据与内容的关键方法是Field类中的get方法。f为一个Field类型的对象,obj是包含f域的类的实例,那么f.get(obj)将返回obj对象中f域的实际数据。

Employee jack = new Employee("jack", 35000, 10, 1, 1998); // name money month day year
Class cl = jack.getClass();
Field f = cl.getDeclaredField("name");
Object ob = f.get(jack);                              //如果是基本类型则会自动装箱

如果name域为private时,上面的代码会抛出IllegalAccessExecption异常,因为 反射机制默认情况下受限于Java的访问控制,但是我们可以跳过安全管理器的控制,只需要调用Field、Method或Constructor对象的setAccessible(boolean)方法,将其设为true,则Field、Method或Constructor对象就可以跳过安全管理器的控制

调用任意方法

反射机制允许调用任意方法,使用Method类的invoke()方法。其使用方法与Field类的get()方法类似

Object invoke(Object obj, Object... args)

第一个参数为执行方法的对象:m为一个Method类的对象,obj是包含m方法的类的实例

其余参数为调用m方法的参数列表

我们首先要获取一个指定的Method对象才能够执行invoke()方法,那一个指定的Method对象如何获取呢,可以有以下两种方法:

  • 对getDeclareMethod方法返回的集合进行遍历,找到指定的方法
  • 使用getMethod方法,通过传入方法名和所有的参数类型即可获得一个指定的方法
Student st = new Student("张三");

Class cl = st.getClass();

//获得Student类的getName()方法的对象
Method get = cl.getMethod("getName");
//获得Student类的setName(String)方法的对象
Method set = cl.getMethod("setName", String.class);

//调用invoke执行相关的方法
String name1 = (String)get.invoke(st);
set.invoke(st, "李四");
String name2 = (String)get.invoke(st);
//name1:张三  name2:李四

Original: https://www.cnblogs.com/shiruyanhai/p/16142156.html
Author: 诗如沿海
Title: Java反射

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607888/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • c#反射

    待总结 posted @2015-03-19 12:58 zhepama 阅读(134 ) 评论() 编辑 Original: https://www.cnblogs.com/zh…

    Java 2023年5月30日
    084
  • 「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之数据库逆向(十二)

    基于Vue和Quasar的前端SPA项目实战之数据库逆向(十二) 回顾 通过之前文章基于Vue和Quasar的前端SPA项目实战之动态表单(五)的介绍,实现了动态表单功能。如果是全…

    Java 2023年6月6日
    0145
  • Java动手又动脑-数组1

    动手又动脑数组第一阶段 posted @2022-03-18 07:52 HelloHui 阅读(10 ) 评论() 编辑 Original: https://www.cnblog…

    Java 2023年6月9日
    043
  • SpringBoot —— Filter 过滤器

    SpringBoot——实现过滤器Filter 1、Filter过滤器 (1) 主要用来过滤用户请求的,允许我们对用户的请求进行前置处理和后置处理。面向切面编程AOP。 例如:实现…

    Java 2023年6月5日
    064
  • C语言-字符串函数的实现(二)之strcpy

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strnc…

    Java 2023年6月10日
    065
  • 对java一点感悟

    都说程序员吃青春饭,也许你可能不信,你会觉得不管哪行哪业都是吃青春饭呀!因为其他行业的知识是大概学完的然后使用一辈子,就比如司机,只要学会开车就行了,然后不断的每天开;比如教师,只…

    Java 2023年6月6日
    075
  • Eureka详解系列(二)–如何使用Eureka(原生API,无Spring)

    简介 通过上一篇博客 Eureka详解系列(一)–先谈谈负载均衡器 ,我们知道了 Eureka 是什么以及为什么要使用它,今天,我们开始研究如何使用 Eureka。 在…

    Java 2023年6月13日
    064
  • 定时执行任务-springboot

    定时执行任务-springboot 先看两个接口 这两个接口springboot已经帮我们封装好了,我们不需要去手动使用 TaskScheduler //任务调度者 TaskExe…

    Java 2023年6月13日
    074
  • Java 从FTP下载.上传文件

    1.需要导入pom <dependency>   <groupId>commons-netgroupId> <art…

    Java 2023年5月29日
    081
  • Spring Cloud Alibaba分布式事务组件 seata 详解(小白都能看懂)

    一,什么是事务(本地事务)? 指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 简单的说,事务就是并发控制的单位,是用户定义的一个操作序列。 _而一个逻辑…

    Java 2023年6月14日
    078
  • Delphi 多线程的例子

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Contr…

    Java 2023年5月29日
    075
  • 7月13日

    sleep和wait 都是让当前现场展示放弃cpu的使用权,进入阻塞状态 方法归属 sleep 是Thread的静态方法 wait,wait(long)都是Object的成员方法,…

    Java 2023年6月6日
    080
  • BindingException问题

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月5日
    071
  • Java连载150-NIO详解(一)

    一、IO原理 1.底层原理 操作系统在进行IO的时候,实际上并不是即时操作,它们是通过缓冲区的,也就是说,我们读写文件都是通过一个中介来进行的。读系统就是把内核缓存区的内容复制到进…

    Java 2023年6月13日
    070
  • 数据结构与算法之递归

    用循环实现阶乘 阶乘的规则就是输入数字n计算乘积.例如n为3计算结果为123。此算法的时间复杂度为O(n) public static long f1(long n) { long…

    Java 2023年6月8日
    077
  • redis哨兵模式下主从切换后,php实现自动切换

    redis的哨兵模式,在主服务器挂掉后,会通过选举将对应的从服务器切换为主服务器,以此来达到服务的高可用性。 在业务层面如果主从做了切换可能相对应的服务器IP地址会发生改变,这样会…

    Java 2023年6月8日
    081
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球