1. 这应该分成两个问题,1.如何获取参数值. 2.如何获取参数名,
  2.  
  3. 1.如何获取参数值。这个是运行时的数据,你程序处理下获取就好了。比如写一个代理
  4.  
  5. 2.参数名是在编译的时候就写入到class文件的。,而这些方法的参数在class中就是一个局部变量。class对于局部变量的定义和存储专门有张表。
    单纯通过反射目前好像没有办法,通过字节码解析倒是可以
    比如下面代码
  6.  
  7. public static void staticMethod(String args1, String args2) {
    }
  8.  
  9. 局部变量表:
    [pc: 0, pc: 1] local: args1 index: 0 type: java.lang.String
    [pc: 0, pc: 1] local: args2 index: 1 type: java.lang.String
  10.  
  11. pc 0是每个字节码指令的程序计数器。[pc: 0, pc: 1] local: args1 index: 0 type: java.lang.String就是说在程序第0个指令到第1个指令的局部变量数组下标为0的变量类型是String变量名是args1.
  12.  
  13. public static void nonStaticMethod(String args1, String args2) {
    }
  14.  
  15. 局部变量表;
    [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
  16.  
  17. 这个方法比上面的方法多了一个this。因为这个方法是非静态方法。
  18.  
  19. 所以如果要获取参数名需要解析字节码。这里给你一段代码使用ASM
  20.  
  21. import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
  22.  
  23. import org.objectweb.asm.ClassVisitor;
    import org.objectweb.asm.MethodVisitor;
    import org.objectweb.asm.Opcodes;
    import org.objectweb.asm.Type;
  24.  
  25. public class ReadMethodArgNameClassVisitor extends ClassVisitor {
  26.  
  27. public Map<String, List<String>> nameArgMap = new HashMap<String, List<String>>();
  28.  
  29. public ReadMethodArgNameClassVisitor() {
    super(Opcodes.ASM5);
    }
  30.  
  31. @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;
    }
    }
  32.  
  33. import java.util.List;
  34.  
  35. import org.objectweb.asm.Label;
    import org.objectweb.asm.MethodVisitor;
  36.  
  37. public class ReadMethodArgNameMethodVisitor extends MethodVisitor {
  38.  
  39. public List<String> argumentNames;
  40.  
  41. public int argLen;
  42.  
  43. public ReadMethodArgNameMethodVisitor(int api) {
    super(api);
    }
  44.  
  45. @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);
    }
    }
  46.  
  47. }
  48.  
  49. public class POJO {
  50.  
  51. public void say(String message, int times){
    }
  52.  
  53. }
  54.  
  55. import java.io.IOException;
    import java.util.List;
    import java.util.Map.Entry;
  56.  
  57. import org.objectweb.asm.ClassReader;
  58.  
  59. public class Test {
  60.  
  61. 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);
    }
    }
    }
  62.  
  63. }
  64.  
  65. 使用asm版本是
  66.  
  67. <dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-all</artifactId>
    <version>5.0.3</version>
    </dependency>
  68.  
  69. 这里存在一个隐患,如果有些class文件做了加密混淆吧局部变量表里面的变量名改变了,那就没法获得源码级别的参数名了。

如何获得JVM执行过程中调用的方法名的更多相关文章

  1. 当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误

    当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示. 有两种方法可以解决以上问题: 1.修改we ...

  2. 只能在执行 Render() 的过程中调用 RegisterForEventValidation(RegisterForEventValidation can only be called during Render();

    只能在执行 Render() 的过程中调用 RegisterForEventValidation(RegisterForEventValidation can only be called durin ...

  3. "只能在执行Render()的过程中调用RegisterForEventValidation" 解决方案

    开发中遇到令人蛋疼的问题: 只能在执行Render()的过程中调用RegisterForEventValidation 当出现的异常的提示: 异常详细信息: System.InvalidOperati ...

  4. 只能在执行 Render() 的过程中调用 RegisterForEventValidation

    当用GridView导出Execl的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示.有两种方法可以解决以上问题: 1.修改web ...

  5. Error 之 只能在执行Render() 的过程中调用 RegisterForEventValidation;

    在实现"将GridView中的数据导出到Excel中"的时候出现了如下错误: 用户代码未处理 InvalidOperationException 只能在执行 Render() 的过 ...

  6. C# asp.net中导出Excel表时总出现"只能在执行 Render() 的过程中调用 RegisterForEventValidation

    C# asp.net中导出Excel表时总出现"只能在执行 Render() 的过程中调用 RegisterForEventValidation 后台添加以下方法:/// <summa ...

  7. 只能在执行Render() 的过程中调用 RegisterForEventValidation;

    October 17, 2008  3:28 PMMarch 29, 2013  8:28 PM Aillo 编程   0 Comments 在实现"将GridView中的数据导出到Exce ...

  8. 问题:只能在执行 Render() 的过程中调用 RegisterForEventValidation;结果:只能在执行 Render() 的过程中调用 RegisterForEventValidation

    只能在执行 Render() 的过程中调用 RegisterForEventValidation 当在导出Execl或Word的时候,会发生只能在执行 Render() 的过程中调用 Register ...

  9. UI5-技术篇-jQuery.ajax执行过程中Token验证及JSON格式传值问题

    最近两天在测试OData服务类方法CREATE_DEEP_ENTITY及GET_EXPANDED_ENTITYSET,刚开始采用ODataModel方式调用没有任何问题,但是ODataModel采用的 ...

随机推荐

  1. delphi 反射(原理)

    关于反射的用途是『降低模块间的耦合度』这个倒未必尽然 单就delphi来说,从实现上看,它的所谓反射是基于RTTI,而RTTI的出现按照官方的说法是为了实现RAD中窗体文件DFM的持久化而产生的,其实 ...

  2. Android:activity跳转过渡效果

    放在startActivity(intent);后面 overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out) ...

  3. MySQL高效分页解决方案集

    一,最常见MYSQL最基本的分页方式: select * from content order by id desc limit 0, 10 在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的 ...

  4. Linux 模拟 鼠标 键盘 事件

    /************************************************************************ * Linux 模拟 鼠标 键盘 事件 * 说明: ...

  5. HDU 1532 Drainage Ditches 排水渠(最大流,入门)

    题意: 给出一个有向图,以及边上的容量上限,求最大流.(有重边,要将容量上限叠加) 思路: 用最简单的EK+BFS解决.每次搜到一条到达终点的路径,就立刻退出,更新ans,然后再回头修改图中的当前fl ...

  6. jquery页面无刷新切换皮肤并保存

    效果体验:http://runjs.cn/detail/hijgcghe <!DOCTYPE html> <html> <head> <meta http-e ...

  7. VS2010 Chromium编译

    推荐使用Windows 7及以后系统,最少8G内存,预留出50G磁盘空间 搭建Visual Studio 2010开发环境 1.安装Visual Studio 2010专业版或者旗舰版 2.安装VS2 ...

  8. linux下Qt问题cannot find -lGL collect2: error: ld returned 1 exit status

    fedora下解决 yum groupinstall "Development Tools" yum install mesa-libGL-devel ubuntu下解决 sudo ...

  9. js基础第八天

    返回前面起第一个字符位置 indexOf("sdfsdf");它是从左边索引为0开始数,而且只找第一个,然后返回该字符的位置.返回是个数值.如果找不到该字符,那么就会返回-1. 返 ...

  10. java双亲委派模型如何递归实现

    以下是Classloader的中最重要的方法,也就是所谓的双亲委派模型.这个模型第一次在周志明的书上看到,当时看了只知道是类加载过程是首先是委托给父加载器,否则父不能加载,则自己加载,整个过程实则是一 ...