Вопрос-ответ

Getting the name of the currently executing method

Получение имени выполняемого в данный момент метода

Есть ли способ получить имя текущего выполняемого метода в Java?

Переведено автоматически
Ответ 1

Технически это будет работать...

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

Однако во время компиляции будет создан новый анонимный внутренний класс (например, YourClass$1.class). Таким образом, будет создан .class файл для каждого метода, который использует этот трюк. Кроме того, при каждом вызове во время выполнения создается неиспользуемый экземпляр объекта. Так что это может быть приемлемым приемом отладки, но он сопряжен со значительными накладными расходами.

Преимущество этого трюка заключается в том, что getEnclosingMethod() возвращает данныеjava.lang.reflect.Method, которые могут быть использованы для извлечения всей другой информации о методе, включая аннотации и имена параметров. Это позволяет различать конкретные методы с одинаковым именем (перегрузка метода).

Обратите внимание, что согласно JavaDoc из getEnclosingMethod() этот трюк не должен вызывать a SecurityException поскольку внутренние классы должны загружаться с использованием того же загрузчика классов. Таким образом, нет необходимости проверять условия доступа, даже если присутствует менеджер безопасности.

Пожалуйста, имейте в виду: это требуется использовать getEnclosingConstructor() для конструкторов. Во время блоков вне (именованных) методов, getEnclosingMethod() возвращаетсяnull.

Ответ 2

Thread.currentThread().getStackTrace() обычно содержит метод, из которого вы его вызываете, но есть подводные камни (см. Javadoc):


Некоторые виртуальные машины при определенных обстоятельствах могут пропускать один или несколько кадров стека из трассировки стека. В крайнем случае виртуальной машине, у которой нет информации о трассировке стека, касающейся этого потока, разрешается возвращать массив нулевой длины из этого метода.


Ответ 3

Январь 2009:
Полный код будет (для использования с учетом предостережения @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 г.:

синие комментарии:


Я использую JRE 6 и выдает неправильное имя метода.
Это работает, если я пишу ste[2 + depth].getMethodName().



  • 0 является getStackTrace(),

  • 1 является getMethodName(int depth) и

  • 2 вызывает метод.


ответ от virgo47 (против) фактически вычисляет правильный индекс для применения, чтобы вернуть имя метода.

Ответ 4

Мы использовали этот код, чтобы уменьшить потенциальную изменчивость индекса трассировки стека - теперь просто вызовите methodName util:

public class MethodNameTest {
private static final int CLIENT_CODE_STACK_INDEX;

static {
// Finds out the index of "this code" in the returned stack trace - funny but it differs in JDK 1.5 and 1.6
int i = 0;
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
i++;
if (ste.getClassName().equals(MethodNameTest.class.getName())) {
break;
}
}
CLIENT_CODE_STACK_INDEX = i;
}

public static void main(String[] args) {
System.out.println("methodName() = " + methodName());
System.out.println("CLIENT_CODE_STACK_INDEX = " + CLIENT_CODE_STACK_INDEX);
}

public static String methodName() {
return Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX].getMethodName();
}
}

Кажется излишне разработанным, но у нас был некоторый фиксированный номер для JDK 1.5, и мы были немного удивлены, что он изменился, когда мы перешли на JDK 1.6. Теперь то же самое в Java 6/7, но вы просто никогда не знаете наверняка. Это не является доказательством изменений в этом индексе во время выполнения - но, надеюсь, HotSpot работает не так уж плохо. :-)

java reflection