javassist

发布于:2025-04-20 ⋅ 阅读:(84) ⋅ 点赞:(0)

使用javassist获取参数名

1,添加依赖

需要在pom.xml文件中添加下面的依赖:

<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.28.0-GA</version>
</dependency>

2,示例代码及详解

// UserController.java
package com.example;

public class UserController {
    public void saveUser(String username, int age) {
        // 方法实现
    }
}

下面是使用 javassist 获取 saveUser 方法参数名的代码:

import javassist.*;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ParameterNameExtractor {
    public static void main(String[] args) throws Exception {
        // 反射获取目标类的方法
        Class<?> targetClass = Class.forName("com.example.UserController");
        Method method = targetClass.getMethod("saveUser", String.class, int.class);

        // 获取 ClassPool 实例,它是 javassist 的类池,用于管理类的字节码
        ClassPool pool = ClassPool.getDefault();
        // 获取目标类的 CtClass 对象,CtClass 表示类的字节码表示
        CtClass ctClass = pool.get(targetClass.getName());

        // 获取方法的参数类型数组
        Class<?>[] parameterTypes = method.getParameterTypes();//参数类型数组
        CtClass[] ctParams = new CtClass[parameterTypes.length];
        for (int i = 0; i < parameterTypes.length; i++) {
            ctParams[i] = pool.getCtClass(parameterTypes[i].getName());
        }

        // 获取目标方法的 CtMethod 对象
        CtMethod ctMethod = ctClass.getDeclaredMethod(method.getName(), ctParams);
        // 获取方法的字节码信息
        MethodInfo methodInfo = ctMethod.getMethodInfo();
        // 获取方法的代码属性
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();

        // 获取方法的局部变量属性,其中包含参数名信息
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
        if (attr == null) {
            System.out.println("未找到局部变量属性,可能编译时未保留参数名信息。");
            return;
        }

        // 确定参数名的起始`在这里插入代码片`位置
        int pos = java.lang.reflect.Modifier.isStatic(method.getModifiers()) ? 0 : 1;
        List<String> parameterNames = new ArrayList<>();
        int parameterCount = method.getParameterCount();
        for (int i = 0; i < parameterCount; i++) {
            // 获取参数名
            String parameterName = attr.variableName(i + pos);
            parameterNames.add(parameterName);
        }

        // 输出参数名
        System.out.println("方法 " + method.getName() + " 的参数名:");
        for (String name : parameterNames) {
            System.out.println(name);
        }
    }
}