如何在Java中获取调用类的名称?

Mar*_*iar 20 java callstack

我想在这件事上提供一些帮助,

例:

public class A {

    private void foo() {

          //Who Invoked me

    }

}

public class B extends A { }

public class C extends A { }

public class D {

     C.foo();

}
Run Code Online (Sandbox Code Playgroud)

这基本上就是这种情况.我的问题是方法foo()怎么知道谁在调用它?

编辑:基本上我试图做一个数据库层,在类AI中将创建一个将生成SQL语句的方法.通过获取调用类的所有公共属性的值来动态生成此类语句.

Bal*_*usC 34

最简单的方法如下:

String className = new Exception().getStackTrace()[1].getClassName();
Run Code Online (Sandbox Code Playgroud)

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

编辑:您评论如下:

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

然后,我强烈建议您根据自己的喜好寻找现有的ORM库,例如Hibernate,iBatis或任何JPA实现.

  • @Mark:这是非常糟糕的设计.我会***深深地重新考虑它. (7认同)
  • @Peter:`Thread.currentThread().getStackTrace()[0] .getMethodName()`总是``getStackTrace"`.猜猜你能搞清楚为什么...... (6认同)
  • @Peter:查看`Thread#getStackTrace()`的源代码.对......它做了一个`new Exception().getStackTrace()`. (2认同)

Fab*_*eeg 14

也许对于您的用例,将调用者的类传递给方法是有意义的,例如:

public class A { public void foo(Class<?> c) { ... } }
Run Code Online (Sandbox Code Playgroud)

并称之为:

public class B { new A().foo(getClass() /* or: B.class */ ); }
Run Code Online (Sandbox Code Playgroud)

  • +1代表+指出*右*方式来做到这一点.让我们不要为这样的事情搞砸堆栈跟踪. (3认同)
  • 是.如果调用者必须采用使用反射来执行任务的基本设计,请将链接清除.传递类或实例. (2认同)

Ali*_*ani 13

Java 9:Stack Walking API

JEP 259为堆栈遍历提供了一种有效的标准API,允许轻松过滤和延迟访问堆栈跟踪中的信息.首先,您应该获得以下实例StackWalker:

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

StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
Run Code Online (Sandbox Code Playgroud)

你可以调用getCallerClass()方法:

Class<?> callerClass = walker.getCallerClass();
Run Code Online (Sandbox Code Playgroud)

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