前言:

复现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知识星球

Java安全初学之反射的更多相关文章

  1. Java类加载和类反射回顾

    今天学习Spring,突然想重新复习一下Java类加载和类反射的.巩固一下底层原理.部分参考了李刚老师的<疯狂Java讲义>和陈雄华.林开雄的<Spring3.x企业应用开发实战&g ...

  2. 【GoLang】golang 如何像Java 一样通过类名反射对象?

    结论: golang不支持解析string然后执行. golang的反射机制只能存在于已经存在的对象上面. 不知道后续的版本有没有规划,现在只能先加载注册,然后实现类似Java工厂模式的反射. 代码示 ...

  3. java学习:用反射构造bean

    先贴一些反射的基本知识:-------------------------------------------------------------------- 一.什么是反射:反射的概念是由Smit ...

  4. 反射那些事儿——Java动态装载和反射技术

    一直以来反射都是只闻其声,却无法将之使用,近日尽心下来学习下,发现了很多精妙之处. Java动态装载和反射技术 一.类的动态装载 1.Java代码编译和执行的整个过程包含了以下三个重要的机制: ● J ...

  5. Java基础学习笔记二十三 Java核心语法之反射

    类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任 ...

  6. Java提升篇之反射的原理

    Java提升篇之反射的原理 1.构造方法的反射 import java.lang.reflect.Constructor; public class ReflectConstructor { publ ...

  7. Java学习:注解,反射,动态编译

    狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! Java学习:注解,反射,动态编译 Annotation 注解  什么是注解 ? Annotat ...

  8. 黑马程序猿————Java基础日常笔记---反射与正則表達式

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 黑马程序猿----Java基础日常笔记---反射与正則表達式 1.1反射 反射的理解和作用: 首 ...

  9. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

随机推荐

  1. Gym 101464C - 计算几何+二分(uva1463)

    不是很难,但是我觉得对代码能力的要求还是挺高的. 注意模块化. 因为是浮点数,所以二分用的很多很多. 参考 https://blog.csdn.net/njupt_lyy/article/detail ...

  2. xss之htmlspecialchars

    源代码: 可以看到是用htmlspecialchars 对get参数message进行处理,但是他默认不对单引号进行处理的. 只对预定义的字符进行处理: & (和号)成为 & &quo ...

  3. unity编辑器扩展学习

    扩展编辑器实际上就是在unity菜单栏中添加一些按钮,可以一键执行一些重复性的工作. 一.添加按钮 1.简单使用MenuItem特性 using UnityEngine; using UnityEdi ...

  4. React components render order All In One

    React components render order All In One components render order / components lifecycle DOM tree ren ...

  5. css & auto height & overflow: hidden;

    css & auto height & overflow: hidden; {overflow: hidden; height: 100%;} is the panacea! {溢出: ...

  6. Electron in Action

    Electron in Action $ yarn add -D electron@latest # OR $ npm i -D electron@latest https://www.electro ...

  7. Taro 版本

    Taro 版本 https://taro-docs.jd.com/taro/versions.html 1.x 1.3.34 https://taro-docs.jd.com/taro/docs/1. ...

  8. WebAssembly JavaScript APIs

    WebAssembly JavaScript APIs https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScrip ...

  9. Nestjs 验证对象数组

    route @Patch(':id') patch(@Param('id') id: string, @Body() removeEssayDto: RemoveEssayDto) { return ...

  10. 新兴公链NGK Global如何借助Defi突围?

    Defi正在掀起持续不减的热度,在过去的一段时间里,以Uniswap为代表的去中心化交易所,使得以太坊重新焕发生机.币价也较以往上涨了50%有余.而且这波热度同样波及到交易所和其他公链市场. 但是波及 ...