前言:

复现fastjson的时候深深意识到了需要好好学习一下Java和Java安全,激情的学习了一番java安全中重要的几部分:反序列化、反射、rmi、动态代理,从反射开始做个总结。

反射:java虚拟机在运行时获取获取类的结构信息并调用其方法和属性

也就是说,反射机制和普通方式最大的区别是,普通方式(也就是我们通过正常的new对象)需要在编译时就找到和检查类的.class文件,而反射机制是在运行时做这一步骤。

反射机制用到的类:
Class:获取类的Class对象
Constructor:通过指定参数创建对象
Method:获取类的方法
Filed: 获取类的属性
Array:动态创建数组,访问数组元素

反射代码举例:

import java.lang.Class;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
//构造方法为私有方法的反射调用
//类为私有 无法通过类newInstance对象 故通过getDeclaredConstructor获取私有构造方法再通过构造方法newInstance实例对象
public class reflectTest1 {
public static void main(String args[]){
try {
Class clazz = Class.forName("java.lang.Runtime");
Constructor con = clazz.getDeclaredConstructor();
con.setAccessible(true);
clazz.getMethod("exec",String.class).invoke(con.newInstance(),"calc.exe");
} catch (Exception e) {
e.printStackTrace();
} }
}

这个例子的代码如何理解呢?看一下这段反射代码中用到的几个概念

获取反射中的class对象:

在反射中,要获取类或调用一个类的方法,我们首先需要获得类的Class对象

有以下三种方式:

1. 使用Class.forName方法(也就是例子中的方法)

2. obj.getClass() 使用类对象的getClass方法

3. Class clz = test.class 这种方法是已经加载了test这个类,再通过此方法获取一个它的Class对象

通过反射创建类对象:

在反射中有两种方式创建类对象

1. 通过Class对象的newInstance方法

2. 通过Constructor对象的newInstance方法

在上个反射的例子中即是使用了Constructor对象的newInstance方法来创建对象,原因是因为使用class.newInstance方法即是调用该类的无参构造函数,而java.lang.runtime类的构造函数是私有的,故不能通过Class对象的newInstance方法创建对象

否则,编译器会报如下错误

获取类的方法、构造方法:

获取类方法:clazz.getMethod、clazz.getDeclaredMethod

这两者的区别在于getDeclaredMethod可以获取类的私有方法,除此以外它们的结构都是一样的,以getDeclaredMethod官方文档举例可知第一个参数为要获取的方法名,之后为要获取的方法的参数类型。

因为java中存在方法重载这一概念,所以我们是无法仅通过函数名来确定一个函数的,故在使用getMethod和getDeclaredMethod时我们需要传入要获取的方法的参数类型列表

获取构造方法:clazz.getConstructor、clazz.getDeclaredConstructor

其实与获取普通方法类似,因此这里就不细说了。

执行方法:

invoke():反射机制使用Method中的invoke方法来调用执行方法,举个简单例子

Method method = clazz.getMethod("setNumber", int.class);
method.invoke(object, 2);

至此,在前面举例代码中所用到的几个关键方法和概念就清晰了。

参考:

https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html

phithon知识星球

最新文章

  1. 由LazyMan联想到的
  2. TranslateAnimation 运行动画后实际位置不正确问题
  3. 【Android端 APP GPU过度绘制】GPU过度绘制及优化
  4. SQL Server 连接超时案例一则
  5. 通过WebViewJavascriptBridge实现OC与JS交互
  6. Java的多线程机制系列:(四)不得不提的volatile及指令重排序(happen-before)
  7. 十分钟搭建个人网站:Jekyll主题BoHu
  8. OpenCV之Python学习笔记
  9. HBuilder打包Android apk 支付不了问题解决
  10. JavaScript(第五天)【流程控制语句】
  11. PHP 二维数组根据某个字段按指定排序方式排序
  12. [python]关于函数传入参数
  13. jenkins了解一下,讲一下jenkins这个鬼东西
  14. 腾讯云centos7安装MySQL
  15. s3 api接口的调用
  16. vue.js及项目实战[笔记]— 02 vue.js基础
  17. 前端如何在h5页面调用微信支付?
  18. 2016 博客导读总结 & 个人感悟
  19. django字段的参数
  20. HDU 3279 二分图最大匹配

热门文章

  1. python常用连接字符串
  2. 记一次亲身体验的勒索病毒事件 StopV2勒索病毒
  3. 踏上Revit二次开发之路 3 自己的工具按钮
  4. 同时拿到BATJMD的Offer是怎样的一种体验?
  5. 【转】REST风格框架实战:从MVC到前后端分离(附完整Demo)
  6. Harbor 镜像仓库搭建
  7. 12.tomcat7切换tomcat8导致cookie异常
  8. sqll-libs(3)
  9. KafkaBroker 简析
  10. u-boot 移植 --->4、Tiny210核心板的DDR初始化下详解