0x00 前言
JAVA安全系列文章主要为了回顾之前学过的java知识,构建自己的java知识体系,并实际地将java用起来,达到熟练掌握java编程,并能用java编写工具的目的。此系列文章需要读者具备一定java基础,不定时更新。相关详情可通过我的公众号文章进行查看:
反射部分文章内容,主要来自B站韩顺平老师JAVA基础课的反射讲解部分,链接:
https://www.bilibili.com/video/BV1fh411y7R8?p=711&vd_source=f50eede57052ba3346254570c978a2ee
本文为JAVA安全系列文章第三篇。
0x01 引出反射机制(为什么和是什么)
1.为什么需要反射机制
现有如下需求:
根据配置文件re.properties指定信息,创建Cat类并调用其hi方法。
按照传统方法,我们会先创建Properties对象去读取re.properties里的classfullpath和method字段,然后读取到类路径new一个对象出来,再调用其方法,但我们读取到的是一个字符串,无法创建对象呀:
注:这种通过外部配置文件,在不修改源码的情况下来控制程序的需求,在框架中应用很多。符合设计模式中的ocp(Open-Closed Principle)原则,即不修改源码(开),扩容功能(闭)。
既然传统方法不能解决,那我们就需要学习新的技术方法—反射机制来解决了:
注:此处若要调用Cat类的cry()方法,只需修改配置文件,无需修改源码
初次接触看不懂?加载类?Class类型的对象?方法也可以是对象?看完下面再回过来看,这些问题都能明白了。
2.反射机制概念
反射机制允许程序在执行期间借助于ReflectionAPI取得任何类的内部信息(比如成员变量,构造器,成员方法等),并能操作对象的属性及方法。通过反射机制我们可以完成:
(1)在运行时判断任意一个对象所属的类
(2)在运行时构造任意一个类的对象
(3)在运行时得到任意一个类所具有的成员变量和方法
(4)在运行时调用任意一个对象的成员变量和方法
(5)生成动态代理
网上大多讲反射的文章,基本都是放上上面一段文字,然后介绍一些API,再来几段代码示例一下,导致看了其实还不是太能理解反射。下面会从原理上来介绍反射。
0x02 反射机制原理
我们的Java程序在计算机中有三个阶段:
1.第一阶段:代码阶段/编译阶段
最开始学习java时,我们都会创建一个.java后缀的文件,然后在里面写上我们的代码。运行前通过javac对其进行编译,得到一个.class后缀的字节码文件
2.第二阶段:类加载阶段(Class类阶段)
当执行new一个对象时,会先通过类加载器ClassLoader将我们所需要的类进行加载(此处就体现了反射),这里的类加载是以.class后缀文件为基础的。加载完后,在堆中会产生一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息(成员变量、构造器、成员方法等),通过这个对象得到类的结构。(Class对象就像是一面镜子,透过这个镜子看到类的结构,故形象的称之为反射)
3.第三阶段:Runtime运行阶段
在运行阶段,我们通过new的方式创建的对象是在堆中,该对象知道它是属于哪个Class对象。若我们得到Class对象,也同样可以通过它来创建对象,调用对象方法,操作属性等。
反射机制原理可以用下图示意:
0x03 与反射相关的主要类
java中与反射相关的类主要有四个:
-
java.lang.Class
代表一个类,Class对象表示某个类加载后在堆中的对象
-
java.lang.reflect.Method
代表类的方法,Method对象表示某个类的方法
-
java.lang.reflect.Field
代表类的成员变量,Field对象表示某个类的成员变量
-
java.lang.reflect.Constructor
代表类的构造方法,Constructor对象表示构造器
通过上面的介绍,可以发现在反射中,成员方法,成员变量,构造器这些均为对象,将Java语言"万物皆对象"的特点表现得淋漓尽致。
这些类中每个类都继承了一些类,实现了一些接口,故每个类都会有很多方法,这些方法有自身的,有父类的,有接口的。拿java.lang.reflect.Method来说,类图是这样的:
其可调用的方法有很多:
使用方法其实都是调用API,我们掌握一些常用的就行,重点在于理解反射的原理。下面是快速入门示例代码:
Cat类:
Reflection01类:
运行效果:
从示例代码中可以看出,方法对象,属性对象,构造器对象都是通过调用Class对象的API来获取的,而后要调用方法、获取属性值、通过构造器去创建对象实例等使用相应对象的API即可。由此可见Class类在反射机制中占有重要地位。
0x04 反射优缺点及优化
-
优点
通过反射我们可以动态创建和使用对象,使用灵活,没有限制。反射机制是框架的灵魂,底层框架的核心,反射机制使得Java能成为一种动态语言。没有反射也就没有框架,Java语言也就成为不了天下第一(狗头)
2.缺点
使用反射基本就是解释执行,对执行速度有影响。
3.反射优化—关闭访问检查
Method、Field、Constructor对象都有setAccessible()方法,其作用是启动和禁用访问安全检查的开关。参数值为true表示反射的对象在使用时取消访问检查,提高反射的效率。参数值为false则表示反射的对象执行访问检查。
具体参看下面代码:
我将上面的代码执行了三轮,结果记录如下:
注:三个方法应分开单独执行。若执行完了第一个方法再去执行第二个方法,那么在第二个方法里创建对象的时间会被缩短,对结果会造成影响,因为类只会被加载一次,每个类在堆中只会有一个Class对象。
由上面的实验结果我们可以得出结论:
(1)当我们创建对象并调用其方法时,传统方法要比使用反射更快
(2)关闭访问安全检查可以使得反射的运行速度快一丢丢。
0x05 总结
本文先通过一个例子来引出反射机制,再介绍了反射概念及作用,然后介绍反射机制的原理(重点),反射相关的四个主要类,反射优缺点及优化,达到了一个快速入门的目的。需掌握的知识点:
-
反射机制的概念、原理、作用
-
反射相关的四个主要类的API的基本使用
-
关闭访问安全检查可以使得反射的运行速度快一丢丢
可能有读者还不太理解Class类到底是什么,这也是反射机制的重点内容,下一篇文章将重点介绍Class类
如果喜欢小编的文章,记得多多转发,点赞+关注支持一下哦~,您的点赞和支持是我最大的动力~
原文始发于微信公众号(沃克学安全):JAVA安全|基础篇:反射机制之快速入门
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论