是否有一种方法来获得Java中当前正在执行的方法的名称?


当前回答

我有解决方案使用这个(在Android)

/**
 * @param className       fully qualified className
 *                        <br/>
 *                        <code>YourClassName.class.getName();</code>
 *                        <br/><br/>
 * @param classSimpleName simpleClassName
 *                        <br/>
 *                        <code>YourClassName.class.getSimpleName();</code>
 *                        <br/><br/>
 */
public static void getStackTrace(final String className, final String classSimpleName) {
    final StackTraceElement[] steArray = Thread.currentThread().getStackTrace();
    int index = 0;
    for (StackTraceElement ste : steArray) {
        if (ste.getClassName().equals(className)) {
            break;
        }
        index++;
    }
    if (index >= steArray.length) {
        // Little Hacky
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[3].getMethodName(), String.valueOf(steArray[3].getLineNumber())}));
    } else {
        // Legitimate
        Log.w(classSimpleName, Arrays.toString(new String[]{steArray[index].getMethodName(), String.valueOf(steArray[index].getLineNumber())}));
    }
}

其他回答

使用以下代码:

    StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
    StackTraceElement e = stacktrace[1];//coz 0th will be getStackTrace so 1st
    String methodName = e.getMethodName();
    System.out.println(methodName);

从技术上讲,这是可行的……

String name = new Object(){}.getClass().getEnclosingMethod().getName();

但是,在编译时将创建一个新的匿名内部类(例如YourClass$1.class)。这将为每个部署这个技巧的方法创建一个。class文件。此外,在运行时的每次调用上都会创建一个未使用的对象实例。因此,这可能是一个可接受的调试技巧,但它确实带来了巨大的开销。

这种技巧的一个优点是getEnclosingMethod()返回java.lang.reflect.Method,该方法可用于检索方法的所有其他信息,包括注释和参数名。这使得区分具有相同名称的特定方法成为可能(方法重载)。

注意,根据getEnclosingMethod()的JavaDoc,这个技巧不应该抛出SecurityException,因为内部类应该使用相同的类装入器装入。因此,即使有安全管理人员在场,也不需要检查访问条件。

请注意:对于构造函数,必须使用getEnclosingConstructor()。在(命名)方法之外的块中,getEnclosingMethod()返回null。

2009年1月: 完整的代码将是(使用@Bombe的警告):

/**
 * Get the method name for a depth in call stack. <br />
 * Utility function
 * @param depth depth in the call stack (0 means current method, 1 means call method, ...)
 * @return method name
 */
public static String getMethodName(final int depth)
{
  final StackTraceElement[] ste = Thread.currentThread().getStackTrace();

  //System. out.println(ste[ste.length-depth].getClassName()+"#"+ste[ste.length-depth].getMethodName());
  // return ste[ste.length - depth].getMethodName();  //Wrong, fails for depth = 0
  return ste[ste.length - 1 - depth].getMethodName(); //Thank you Tom Tresansky
}

更多关于这个问题。

2011年12月更新:

蓝色的评论:

我使用JRE 6,给我不正确的方法名。 如果我写ste[2 + depth]. getmethodname(),它就会起作用。 0是getStackTrace(), 1是getMethodName(int depth)和 2是调用方法。

Virgo47的答案(获得好评)实际上计算了要应用的正确索引,以获得方法名。

MethodHandles.lookup().lookupClass().getEnclosingMethod().getName();

我使用这个代码片段与最新的Android Studio与最新的Java更新。它可以从任何活动、片段等调用。

public static void logPoint() {
    String[] splitPath = Thread.currentThread().getStackTrace()[3]
        .toString().split("\\.");

    Log.d("my-log", MessageFormat.format("{0} {1}.{2}",
        splitPath[splitPath.length - 3],
        splitPath[splitPath.length - 2],
        splitPath[splitPath.length - 1]
    ));
}

像这样叫它

logPoint();

输出

... D/my-log: MainActivity onCreate[(MainActivity.java:44)]