博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
获取Java方法参数的名称
阅读量:5745 次
发布时间:2019-06-18

本文共 5024 字,大约阅读时间需要 16 分钟。

最近有个需求,需要获取java方法参数的名称,网上查了下,然后自己也实践了下,总结出3点:

1.能不能获取方法参数的名称取决于class文件里是否含有LocalVariableTable。
2.javac编译生成的class文件不含有LocalVariableTable,但是eclipse编译生成的class文件却含有LocalVariableTable。
3.有2种方式可以获得,用Asm和Javassist,Asm的性能略高。
贴代码:
maven依赖:

org.javassist
javassist
3.18.0-GA
org.ow2.asm
asm
4.1

User类:

/** *  * @author yankai * @date 2013-7-17 */public class User {		String name;	String address;	int age;		public User(String name, String address, int age) {		this.name = name;		this.address = address;		this.age = age;	}		public static User newInstance(String name, String address, int age) {		return new User(name, address, age);	}		public User copy(String name, String address, int age) {		return new User(name, address, age);	}}

asm实现:

import java.lang.reflect.Method;import java.lang.reflect.Modifier;import org.objectweb.asm.ClassReader;import org.objectweb.asm.ClassVisitor;import org.objectweb.asm.Label;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;/** * @author yankai * @date 2013-7-17 */public class AsmTool {		private static boolean sameType(Type[] types, Class
[] clazzes) { if (types.length != clazzes.length) { return false; } for (int i = 0; i < types.length; i++) { if (!Type.getType(clazzes[i]).equals(types[i])) { return false; } } return true; } public static String[] getMethodParamNames(final Method m) throws Exception { final String[] paramNames = new String[m.getParameterTypes().length]; String methodClass = m.getDeclaringClass().getName(); ClassReader cr = new ClassReader(methodClass); cr.accept(new ClassVisitor(Opcodes.ASM4) { @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { Type[] args = Type.getArgumentTypes(desc); if (!name.equals(m.getName()) || !sameType(args, m.getParameterTypes())) { return null; } return new MethodVisitor(Opcodes.ASM4) { @Override public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { int i = index - 1; if (Modifier.isStatic(m.getModifiers())) { i = index; } if (i >= 0 && i < paramNames.length) { paramNames[i] = name; } } }; } }, 0); return paramNames; }}

asm测试:

import java.lang.reflect.Method;import java.util.Arrays;/** *  * @author yankai * @date 2013-7-17 */public class TestAsm {	public static void main(String[] args) throws Exception {		long start = System.currentTimeMillis();		final Method method = 				User.class.getMethod("newInstance", new Class
[]{String.class, String.class, int.class}); String[] s = AsmTool.getMethodParamNames(method); System.out.println(Arrays.toString(s)); System.out.println(System.currentTimeMillis() - start);//40 }}

javassist实现:

import javassist.ClassPool;import javassist.CtClass;import javassist.CtMethod;import javassist.Modifier;import javassist.bytecode.CodeAttribute;import javassist.bytecode.LocalVariableAttribute;import javassist.bytecode.MethodInfo;/** *  * @author yankai * @date 2013-7-17 */public class JavassistTool {		// 
static final Map
pool2map = new ConcurrentHashMap
(); public static String[] getMethodParamNames(Method method) throws Exception { Class
clazz = method.getDeclaringClass(); String methodName = method.getName(); ClassPool pool = ClassPool.getDefault(); CtClass cc = null; try { cc = pool.get(clazz.getName()); } catch (Exception e) { if (e instanceof NotFoundException) { pool = pool2map.get(clazz.getClassLoader()); if (pool == null) { pool = new ClassPool(true); pool.appendClassPath(new LoaderClassPath(clazz.getClassLoader())); pool2map.put(clazz.getClassLoader(), pool); } } } cc = pool.get(clazz.getName()); CtMethod cm = cc.getDeclaredMethod(methodName); MethodInfo methodInfo = cm.getMethodInfo(); CodeAttribute codeAttribute = methodInfo.getCodeAttribute(); LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag); if (attr == null) { throw new IllegalStateException("LocalVariableAttribute is null"); } String[] paramNames = new String[cm.getParameterTypes().length]; int offset = Modifier.isStatic(cm.getModifiers()) ? 0 : 1; for (int i = 0; i < paramNames.length; i++) { paramNames[i] = attr.variableName(i + offset); } return paramNames; }}

javassist测试:

import java.util.Arrays;/** *  * @author yankai * @date 2013-7-17 */public class TestJavassist {	public static void main(String[] args) throws Exception {		long start = System.currentTimeMillis();		String[] paramNames = JavassistTool.getMethodParamNames(User.class, "newInstance");		System.out.println(Arrays.toString(paramNames));		System.out.println(System.currentTimeMillis() - start);//90	}}

转载地址:http://niozx.baihongyu.com/

你可能感兴趣的文章
Linux的netstat命令使用
查看>>
lvm讲解,磁盘故障小案例
查看>>
大快网站:如何选择正确的hadoop版本
查看>>
经过这5大阶段,你离Java程序员就不远了!
查看>>
IntelliJ IDEA 连接数据库详细过程
查看>>
thymeleaf 学习笔记-基础篇
查看>>
PHP-X开发扩展
查看>>
android学习笔记——onSaveInstanceState的使用
查看>>
工作中如何做好技术积累
查看>>
怎么用sysLinux做U盘双PE+DOS??
查看>>
Spring Transactional
查看>>
shell脚本实例
查看>>
我的友情链接
查看>>
Windows Phone 7 隔离存储空间资源管理器
查看>>
Microsoft Excel 2000/2003修复工具
查看>>
apache安装报错undefined reference ssl
查看>>
关于爱情只有一句忠告
查看>>
CentOS 7下安装部署Oracle11g图文教程
查看>>
F#初学笔记06
查看>>
实战:将企业域名解析委派给企业DNS服务器
查看>>