java - 获取调用者方法 (java.lang.reflect.Method)

标签 java reflection

我想获取调用方法java.lang.reflect.Method不是方法的名称。

这是一个如何获取调用者类的示例。

// find the callers class
Thread t = Thread.getCurrentThread();
Class<?> klass = Class.forName(t.getStackTrace()[2].getClassName());
// do something with the class (like processing its annotations)
... 

仅供测试!

最佳答案

如果它只是为了测试,那么这可能会起作用。它假定类文件可通过调用类的 ClassLoader 访问,并且类文件是使用调试符号编译的(我希望它们用于测试!)。此代码依赖于 ASM bytecode library .

public static Method getMethod(final StackTraceElement stackTraceElement) throws Exception {
    final String stackTraceClassName = stackTraceElement.getClassName();
    final String stackTraceMethodName = stackTraceElement.getMethodName();
    final int stackTraceLineNumber = stackTraceElement.getLineNumber();
    Class<?> stackTraceClass = Class.forName(stackTraceClassName);

    // I am only using AtomicReference as a container to dump a String into, feel free to ignore it for now
    final AtomicReference<String> methodDescriptorReference = new AtomicReference<String>();

    String classFileResourceName = "/" + stackTraceClassName.replaceAll("\\.", "/") + ".class";
    InputStream classFileStream = stackTraceClass.getResourceAsStream(classFileResourceName);

    if (classFileStream == null) {
        throw new RuntimeException("Could not acquire the class file containing for the calling class");
    }

    try {
        ClassReader classReader = new ClassReader(classFileStream);
        classReader.accept(
                new EmptyVisitor() {
                    @Override
                    public MethodVisitor visitMethod(int access, final String name, final String desc, String signature, String[] exceptions) {
                        if (!name.equals(stackTraceMethodName)) {
                            return null;
                        }

                        return new EmptyVisitor() {
                            @Override
                            public void visitLineNumber(int line, Label start) {
                                if (line == stackTraceLineNumber) {
                                    methodDescriptorReference.set(desc);
                                }
                            }
                        };
                    }
                },
                0
            );
    } finally {
        classFileStream.close();
    }

    String methodDescriptor = methodDescriptorReference.get();

    if (methodDescriptor == null) {
        throw new RuntimeException("Could not find line " + stackTraceLineNumber);
    }

    for (Method method : stackTraceClass.getMethods()) {
        if (stackTraceMethodName.equals(method.getName()) && methodDescriptor.equals(Type.getMethodDescriptor(method))) {
            return method;
        }
    }

    throw new RuntimeException("Could not find the calling method");
}

关于java - 获取调用者方法 (java.lang.reflect.Method),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4024587/

相关文章:

Java,获取实现特定接口(interface)的 URLClassLoader 可用的所有类

java - 是否可以模拟通过反射访问的嵌套对象?

java - 与网页自动交互

java - 抛出哪个异常?

java - 将类类型作为参数传递以在 ArrayList 中使用?

java - 使用反射的非虚方法调用

java - null 真的很特别吗?

java - 属性文件不起作用

java - 在 gradle 中运行应用程序所需的模块文件

c# - 使用运算符 <、<= 等测试两个对象