如何在Java中获取调用类的名称?Java 9: Stack Walk API

2022-09-01 19:42:46

我想在这个问题上得到一些帮助,

例:

public class A {
    private void foo() {
        //Who invoked me?
    }
}

public class B extends A {}

public class C extends A {}

public class D {
     C.foo();
}

这基本上就是这种情况。我的问题是,方法如何知道谁在召唤它?foo()

编辑:基本上我正在尝试做一个数据库层,在我将创建一个将生成SQL语句的方法。此类语句是通过获取调用 的所有属性的值动态生成的。class Apublicclass


答案 1

最简单的方法如下:

String className = new Exception().getStackTrace()[1].getClassName();

但实际上,除非出于某些日志记录目的,否则应该不需要这样做,因为这是一项相当昂贵的任务。这是什么,你认为这是解决方案的问题?我们可能会提出更好的建议。

编辑:您评论如下:

基本上,我正在尝试做一个数据库层,在类A中,我将创建一个将生成sql语句的方法,这些语句是通过获取调用类的所有公共属性的值来动态生成的。

然后,我强烈建议寻找现有的ORM库,例如HibernateiBatis或任何JPA实现


答案 2

Java 9: Stack Walk API

JEP 259 为堆栈行走提供了一个高效的标准 API,允许轻松筛选和延迟访问堆栈跟踪中的信息。首先,您应该获得一个实例:StackWalker

import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;
// other imports

StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);

之后,您可以调用该方法:getCallerClass()

Class<?> callerClass = walker.getCallerClass();

无论您如何配置实例,该方法都将忽略反射帧,隐藏帧以及与s相关的帧。此外,不应在第一个堆栈帧上调用此方法。StackWalkergetCallerClassMethodHandle