如何获得JVM执行过程中调用的方法名
这应该分成两个问题,1.如何获取参数值. 2.如何获取参数名, 1.如何获取参数值。这个是运行时的数据,你程序处理下获取就好了。比如写一个代理 2.参数名是在编译的时候就写入到class文件的。,而这些方法的参数在class中就是一个局部变量。class对于局部变量的定义和存储专门有张表。
单纯通过反射目前好像没有办法,通过字节码解析倒是可以
比如下面代码 public static void staticMethod(String args1, String args2) {
} 局部变量表:
[pc: 0, pc: 1] local: args1 index: 0 type: java.lang.String
[pc: 0, pc: 1] local: args2 index: 1 type: java.lang.String pc 0是每个字节码指令的程序计数器。[pc: 0, pc: 1] local: args1 index: 0 type: java.lang.String就是说在程序第0个指令到第1个指令的局部变量数组下标为0的变量类型是String变量名是args1. public static void nonStaticMethod(String args1, String args2) {
} 局部变量表;
[pc: 0, pc: 1] local: this index: 0 type: asmtest.Test
[pc: 0, pc: 1] local: args1 index: 1 type: java.lang.String
[pc: 0, pc: 1] local: args2 index: 2 type: java.lang.String 这个方法比上面的方法多了一个this。因为这个方法是非静态方法。 所以如果要获取参数名需要解析字节码。这里给你一段代码使用ASM import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; public class ReadMethodArgNameClassVisitor extends ClassVisitor { public Map<String, List<String>> nameArgMap = new HashMap<String, List<String>>(); public ReadMethodArgNameClassVisitor() {
super(Opcodes.ASM5);
} @Override
public MethodVisitor visitMethod(int access, String name, String desc,
String signature, String[] exceptions) {
Type methodType = Type.getMethodType(desc);
int len = methodType.getArgumentTypes().length;
List<String> argumentNames = new ArrayList<String>();
nameArgMap.put(name, argumentNames);
ReadMethodArgNameMethodVisitor visitor = new ReadMethodArgNameMethodVisitor(Opcodes.ASM5);
visitor.argumentNames = argumentNames;
visitor.argLen = len;
return visitor;
}
} import java.util.List; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; public class ReadMethodArgNameMethodVisitor extends MethodVisitor { public List<String> argumentNames; public int argLen; public ReadMethodArgNameMethodVisitor(int api) {
super(api);
} @Override
public void visitLocalVariable(String name, String desc, String signature,
Label start, Label end, int index) {
if("this".equals(name)) {
return;
}
if(argLen-- > 0) {
argumentNames.add(name);
}
} } public class POJO { public void say(String message, int times){
} } import java.io.IOException;
import java.util.List;
import java.util.Map.Entry; import org.objectweb.asm.ClassReader; public class Test { public static void main(String... args1) throws IOException {
ClassReader cr = new ClassReader("POJO");
ReadMethodArgNameClassVisitor classVisitor = new ReadMethodArgNameClassVisitor();
cr.accept(classVisitor, 0);
for(Entry<String, List<String>> entry : classVisitor.nameArgMap.entrySet()) {
System.out.println(entry.getKey());
for(String s : entry.getValue()) {
System.out.println(" " + s);
}
}
} } 使用asm版本是 <dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
<version>5.0.3</version>
</dependency> 这里存在一个隐患,如果有些class文件做了加密混淆吧局部变量表里面的变量名改变了,那就没法获得源码级别的参数名了。
如何获得JVM执行过程中调用的方法名的更多相关文章
- 当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误
当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示. 有两种方法可以解决以上问题: 1.修改we ...
- 只能在执行 Render() 的过程中调用 RegisterForEventValidation(RegisterForEventValidation can only be called during Render();
只能在执行 Render() 的过程中调用 RegisterForEventValidation(RegisterForEventValidation can only be called durin ...
- "只能在执行Render()的过程中调用RegisterForEventValidation" 解决方案
开发中遇到令人蛋疼的问题: 只能在执行Render()的过程中调用RegisterForEventValidation 当出现的异常的提示: 异常详细信息: System.InvalidOperati ...
- 只能在执行 Render() 的过程中调用 RegisterForEventValidation
当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示.有两种方法可以解决以上问题: 1.修改web ...
- Error 之 只能在执行Render() 的过程中调用 RegisterForEventValidation;
在实现"将GridView中的数据导出到Excel中"的时候出现了如下错误: 用户代码未处理 InvalidOperationException 只能在执行 Render() 的过 ...
- C# asp.net中导出Excel表时总出现"只能在执行 Render() 的过程中调用 RegisterForEventValidation
C# asp.net中导出Excel表时总出现"只能在执行 Render() 的过程中调用 RegisterForEventValidation 后台添加以下方法:/// <summa ...
- 只能在执行Render() 的过程中调用 RegisterForEventValidation;
October 17, 2008 3:28 PMMarch 29, 2013 8:28 PM Aillo 编程 0 Comments 在实现"将GridView中的数据导出到Exce ...
- 问题:只能在执行 Render() 的过程中调用 RegisterForEventValidation;结果:只能在执行 Render() 的过程中调用 RegisterForEventValidation
只能在执行 Render() 的过程中调用 RegisterForEventValidation 当在导出Execl或Word的时候,会发生只能在执行 Render() 的过程中调用 Register ...
- UI5-技术篇-jQuery.ajax执行过程中Token验证及JSON格式传值问题
最近两天在测试OData服务类方法CREATE_DEEP_ENTITY及GET_EXPANDED_ENTITYSET,刚开始采用ODataModel方式调用没有任何问题,但是ODataModel采用的 ...
随机推荐
- ajax跨域访问的解决方案
今天的工作中要访问摄像机内部的一个web站点,这就涉及到jquery的ajax跨域访问的问题.我使用的是jquery1.7的版本,下面总结如下: 问题一:一开始用IE调试,总是返回No Transpo ...
- 91. Decode Ways
题目: A message containing letters from A-Z is being encoded to numbers using the following mapping: ' ...
- Django自定义用户认证系统Customizing authentication
扩展已有的用户模型Extending the existing User model 有两种方法来扩展默认的User Model而不用重写自己的模型.如果你不需要改变存储在数据库中的字段,而只是需要改 ...
- laravel Authentication and Security
Creating the user modelFirst of all, we need to define the model that is going to be used to represe ...
- 理解 PHP 中的 Streams
Streams 是PHP提供的一个强有力的工具,我们常常在不经意会使用到它,如果善加利用将大大提高PHP的生产力. 驾驭Streams的强大力量后,应用程序将提升到一个新的高度. 下面是PHP手册中对 ...
- Grunt 初体验
对于没有接触过类似自动化工具的朋友,对 grunt 也许只是停留在听过阶段,而并没有真正的使用过.今天就从最初级的教程说起.在开始教程之前,需要先确保你已经安装了 node. 下面就开始来讲解 gru ...
- virtualbox怎么装系统OVA虚拟包大全一键安装
1 第一步,下载ova虚拟包 http://pan.baidu.com/s/1hqxWkUo . 里面有win7.ubuntu.kali,你自己挑一个需要的 全都可以自动缩放屏幕,有VirtualBo ...
- poj 2524 Ubiquitous Religions (并查集)
题目:http://poj.org/problem?id=2524 题意:问一个大学里学生的宗教,通过问一个学生可以知道另一个学生是不是跟他信仰同样的宗教.问学校里最多可能有多少个宗教. 也就是给定一 ...
- [POJ 3788] Interior Points of Lattice Polygons
同swustoj 169 Interior Points of Lattice Polygons Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
- 西南科技大学第十届ACM程序设计竞赛题解
A.德州扑克 B. 我恨11(1089) 问题描述 11是一个孤独的数字,小明十分讨厌这个数字,因此如果哪个数字中出现了11或者该数字是11的倍数,他同样讨厌这个数字.现在问题来了,在闭区间[L,R] ...