Java:获取当前正在执行的Method对应的对象

时间:2011-02-28 09:10:14

标签: java reflection

将当前正在执行的方法作为Method对象的最优雅方法是什么?

我的第一个明显的方法是在helper类中使用静态方法,它将加载当前线程堆栈,获取正确的堆栈跟踪元素,并根据其信息构造Method元素。

有没有更优雅的方法来实现这一目标?

3 个答案:

答案 0 :(得分:16)

深入讨论此主题in this SO Question

我需要做同样的事情,我找到了最好的解决方案,成为@alexsmail提供的解决方案。

看起来有点hacky,但一般的想法是你在方法中声明一个本地类,然后利用class.getEnclosingMethod();

从@ alexsmail的解决方案稍加修改的代码:

public class SomeClass {
   public void foo(){
      class Local {};
      Method m = Local.class.getEnclosingMethod();
   }
 }

答案 1 :(得分:2)

开箱即用,我不知道更好的方法。

要考虑的一件事可能是方面 - 您可以将一个方面编织到围绕所有方法调用的代码中,并将当前的Method对象推送到ThreadLocal(基于可从连接点获得的反射信息)

如果真的触发所有方法,这可能会非常昂贵,但是根据你对结果做了什么,你可以将捕获限制在某些包/类中,这会有所帮助。您也可以推迟Method的实际查找,直到它被使用为止,而是存储方法和参数的名称等。

我怀疑是否会有一种特别便宜的方法来实现这一目标。

答案 2 :(得分:0)

我发现这很有效:

package com.paintedintel.util;

public class Log{

    public static void out(final String output) {
        System.out.println(output);
    }
    
    public static void debug(String output) {
        System.err.println(Log.currentLocation() + " " + output);
    }
    
    public static String currentLocation() {
        StackTraceElement classMethod = new Throwable() 
                .getStackTrace()[2];
        String   currMethod = classMethod.getMethodName(); 
        String   fullClass  = classMethod.getClassName();
        String[] smplClass  = fullClass.split("\\.");
        return smplClass[smplClass.length - 1] + "." + currMethod;
    }   
}

你可以称之为

Log.debug("my message " + myParameters);

我让它打印出 simpleClassName() 而不是包类名,你不能直接得到它

split("\\."); //yes you need to escape the "."

除此之外,它还可以自动跟踪调试输出的来源。或者你可以用它来获取方法和类名。

如果结合 debug 和 currentLocation 方法,则必须使用较低的索引来获取所需的行....

        StackTraceElement classMethod = new Throwable() 
                .getStackTrace()[2]; // use a different index [x] w/exr methods