Java的反射机制
简介
什么是反射?
在运行状态中
- 对于任意一个类,都能够获取到这个类的所有属性和方法
- 对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性)
这种动态获取信息以及动态调用对象的方法的功能就称为java语言的反射机制
也就是说,虽然我们获取不到该类的源代码,但是通过该类的.class文件能反射(Reflect)出这些信息
简单来说
反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息
原理
略…
获取.class字节码文件对象的四种方式
1 | //方法一 |
反射中常用的方法
- 获取指定构造器的方法
getConstructor(int.class.String.class)
- 获取全部构造方法
getContstructor()
- 获取指定成员变量
getDeclaredField("id")
- 获取全部成员变量
getDeclaredFields()
- 实例化
newInstance()
- 获取方法
getMethod("test",String.class)
test
为方法名字,String.class
为参数类型,无参数可空
- 执行获得的方法
invoke(class,"test")
class
为一个实例,test
是向我们要执行的方法中传入的参数
实例
Runtime类执行任意代码
1 | public static void main(String[] args) throws IOException { |
可以成功弹出计算器
下面跟进这个Runtime类,看一下到底调用了个啥
1 | private static Runtime currentRuntime = new Runtime(); |
可以看到getRuntime方法将会返回一个Runtime类得实例,在通过这个实例去调用exec方法,进而执行命令
反射执行
1 | public static void main(String args[]) throws Exception{ |
解析代码
Class.forName("java.lang.Runtime")
获取Runtime类得字节码对象- 调用
getMethod
方法指定获取getRuntime
方法- 此处
new Class[]{}
可省略
- 此处
- 通过
invoke
执行获取到Runtime
类得实例 - 在获取
exec
方法,calc.exe
就是exec
方法执行的代码
其实也可以写成一句话
1 | Class.forName("java.lang.Runtime").getMethod("exec", String.class).invoke(Class.forName("java.lang.Runtime").getMethod("getRuntime",new Class[]{}).invoke(null),"calc.exe"); //执行函数 |
end
下一篇分析java的经典利用链