1

我怎么知道哪个类调用了方法?

class A {
   B b = new B();

   public void methodA() {
    Class callerClass = b.getCallerCalss(); // it should be 'A' class
   } 
}

class B {
 public Class getCallerCalss() {
   //... ???
   return clazz;
 }
}
4

4 回答 4

4

这很容易用Thread.currentThread().getStackTrace().

public static void main(String[] args) {
    doSomething();
}

private static void doSomething() {
    System.out.println(getCallerClass());
}

private static Class<?> getCallerClass() {
    final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    String clazzName = stackTrace[3].getClassName();
    try {
        return Class.forName(clazzName);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        return null;
    }
}

[3]之所以使用,是因为[0]是元素 for Thread.currentThread()[1]是 for getCallerClass[2]是 for doSomething,最后[3]是 is main。如果你放入doSomething另一个类,你会看到它返回了正确的类。

于 2012-09-24T15:24:36.600 回答
3

有一种观察堆栈跟踪的方法

StackTraceElement[] elements = Thread.currentThread().getStackTrace()

Javadoc

数组的最后一个元素表示堆栈的底部,它是序列中最近的方法调用。

于 2012-09-24T15:14:36.137 回答
3

您可以通过获取堆栈跟踪的第二个元素来获取调用者类的类名:

final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
System.out.println(stackTrace[1].getClassName());

该类的getClassName方法StackTraceElement以 a 返回,因此不幸的String是您不会得到对象。Class

于 2012-09-24T15:15:34.057 回答
0

试试Throwable.getStackTrace()

创建一个新的Throwable..你不必扔它:)。

未经测试:

Throwable t = new Throwable();
StackTraceElement[] es = t.getStackTrace();
// Not sure if es[0] would contain the caller, or es[1]. My guess is es[1].
System.out.println( es[0].getClass() + " or " + es[1].getClass() + " called me.");

显然,如果您正在创建某个函数 ( getCaller()),那么您将不得不在堆栈跟踪中再上一层。

于 2012-09-24T15:13:56.183 回答