网站首页 > java教程 正文
点关注,不迷路;持续更新Java相关技术及资讯!!!
什么是反射
。在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。那么我们又能利用反射做什么呢?
- 在运行时分析类。
- 在运行时查看对象,我们还可以利用反射编写一个toString方法供所有类使用。
- 利用Method对象,在运行时任意调用一个对象的方法。
那么本篇文章将围绕者上面三个点来了解一下Java的反射机制。在开始之前,我们先来介绍一下一个类,这个类是我们在使用反射的过程中必不可少会使用到的一个类。
Class类
在运行时,Java运行时系统会为每一个对象都维护一个标识这个对象类型的信息,而保存这些信息的类型就是Class类。我们可以通过对象的getClass()方法来获取该对象对于的Class对象,就像下面这样。
User user = new User(); Class c = user.getClass();
这个世界上的任何东西都有它存在的意义,那么我们可以用Class对象来干什么呢?我们最常使用Class来判断一个对象是不是属于某个类型,就像下面这样:
User user = new User(); if (user.getClass() == User.class) { System.out.println("user is User"); }
当然我们也经常会使用Class类的getName()方法来获取某个类的名称。有写时候,我们还会利用它的newInstance()方法来获取某个类型的实例(当这类没有提供共有的构造方法时)。
关注公众号:Java大型网站架构(免费获取)Java架构、面试、笔记等资料
利用反射分析类
分析一个类,无外乎就是查看这个类中的属性、方法以及其构造方法了。在Java的反射包中提供了三个类Field、Method以及Constructor来分别描述属性、方法和构造器。 下面我们就分别来看下,我们是如何通过反射机制来获取一个类的这些信息的。
1.获取属性
User user = new User(); Class cl = user.getClass(); Field[] fields1 = cl.getFields(); Field[] fields2 = cl.getDeclaredFields();
可以看到我们可以利用getFields()和getDeclaredFields()两个方法来获取类中的属性列表,那么这两个方法有什么区别呢?区别就是前者只会返回类的共有成员信息,而后者这会返回类中所有的成员信息包括公有的、私有的、受保护的,但是不包括父类的成员信息。
2.获取构造器
Constructor[] constructors1 = cl.getConstructors(); Constructor[] constructors2 = cl.getDeclaredConstructors();
3.获取方法
Method[] methods1 = cl.getMethods(); Method[] methods2 = cl.getDeclaredMethods();
可以看到我们可以通过一个类的Class对象很轻松的获取他的属性、构造器以及方法信息。但是在Field、Constructor以及Method中又分别提供了哪些api呢?下面我们就一起来看下。
1.getName()方法,用来获取对应的名称。同时存在于Field、Constructor以及Method类中。
2.getModifiers()方法来获取前面的修饰符(public等),但是getModifiers()返回的是一个int值,我们可以通过Modifier.toString(int i)将其转换成对应的字符串。也同样同时存在于Field、Constructor以及Method类中。
3.getParameterTypes()方法,用来获取方法的参数类型数组。存在于Constructor以及Method类中
4.getReturnType()方法,用来获取方法的返回类型。只存在于Method类中
有了这些api,我们就拥有了在运行时分析一个类的能力,我们可以通过一个简单的小例子来实践一下,我们可以编写一个方法来输出一个类的完整信息,具体的实现会在文末给出,大家可以先自己尝试一下。
利用反射查看对象
有些时候呢,我们可能也需要反射去获取对象中属性的值,比如说在导出Excel的时候,我们只知道列所对应属性的字段名称,然后我们需要通过反射获取它的值,然后把它写到Excel中。那么这节内容就一起来看下如何利用Java的反射机制来分析对象。
User user = new User(1,"itweknow"); Class cl = user.getClass(); Field userName = cl.getDeclaredField("userName"); Object value = userName.get(user);
就像上面的代码一样,我们可以使用Field类中提供的get(Object obj)方法来获取属性的值,对于基础类型还提供了特定的get方法,比如getDouble()。但是如果上面的userName是个私有属性的话,get()方法肯定会抛出IllegalAccessException的异常。这是时候我们需要使用setAccessible()方法覆盖安全管理器的访问控制。
User user = new User(1,"itweknow"); Class cl = user.getClass(); Field userName = cl.getDeclaredField("userName"); userName.setAccessible(true); Object value = userName.get(user);
setAccessible()方法在Field、Method、Constructor类中都有提供。与get()方法呼应,Field还提供了set()方法用来给属性设置值。
利用反射调用任何方法
在Method类中提供了invoke()方法来调用,当前Method对象所包装的方法。invoke()方法的定义如下:
Object invoke(Object obj, Object... args)
第一个参数是调用这个方法的对象,第二个参数是该方法的参数,是一个数组的形式。下面我们就来看下如何利用反射来调用User类中的sayHello()方法吧。
Method sayHelloMethod = cl.getDeclaredMethod("sayHello", String.class); sayHelloMethod.setAccessible(true); sayHelloMethod.invoke(user, "Reflect");
看上面的代码我们通过getDeclaredMethod()方法来获取了一个名为sayHello的私有方法(PS:如果是公有方法的话直接使用getMethod()方法就可以了),同样对于私有方法,我们需要修改它的访问控制才能顺利调用。
API整理
上面的章节中提到了不少Java反射机制中提供的Api,下面是我整理的一些常用的反射Api,大家可以参考一下。
1.Class类
2.Field类
3.Method类
4.Constructor类
5.AccessibleObject类
结束语
这篇文章主要和大家一起了解了一下Java的反射机制,以及在反射包下Field、Method、Constructor三个类所提供的api。
关注公众号:Java大型网站架构(免费获取)Java架构、面试、源码等资料
本文到这里就结束了,喜欢的朋友可以帮忙转发和评论一下,感谢支持!
猜你喜欢
- 2024-09-30 java反射机制深度探讨(java反射机制的原理和用途)
- 2024-09-30 Java中的反射到底有什么用?(java反射的用途及实现)
- 2024-09-30 JAVA 反射机制(Java反射机制的作用包括)
- 2024-09-30 Java的反射机制是什么?#干货分享(java反射机制实现原理)
- 2024-09-30 Java基础:反射机制(java反射机制实例)
- 2024-09-30 想成为java架构师,你首先得掌握的Java反射机制,安排
- 2024-09-30 Java面试篇基础部分-Java反射机制是什么
- 2024-09-30 谈谈Java反射机制(java的反射机制)
- 2024-09-30 Java后端精选技术:Java的反射机制
- 2024-09-30 Java的反射机制大家都会了,你还不会吗?
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)