Как мы можем напечатать номера строк в журнал в Java - PullRequest
126 голосов
/ 22 сентября 2008

Как напечатать номера строк в журнал. Скажем, при выводе некоторой информации в журнал, я также хочу напечатать номер строки, где этот вывод находится в исходном коде. Как мы видим из трассировки стека, он отображает номер строки, где произошло исключение. Трассировка стека доступна для объекта исключения.

Другой альтернативой может быть, например, ручное включение номера строки при печати в журнал. Есть ли другой способ?

Ответы [ 19 ]

94 голосов
/ 22 сентября 2008

От Ангсуман Чакраборты :

/** Get the current line number.
 * @return int - Current line number.
 */
public static int getLineNumber() {
    return Thread.currentThread().getStackTrace()[2].getLineNumber();
}
71 голосов
/ 02 декабря 2010

В итоге мы использовали специальный класс для нашей работы на Android:

import android.util.Log;    
public class DebugLog {
 public final static boolean DEBUG = true;    
 public static void log(String message) {
  if (DEBUG) {
    String fullClassName = Thread.currentThread().getStackTrace()[2].getClassName();
    String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
    String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
    int lineNumber = Thread.currentThread().getStackTrace()[2].getLineNumber();

    Log.d(className + "." + methodName + "():" + lineNumber, message);
  }
 }
}
32 голосов
/ 06 мая 2011

Быстрый и грязный путь:

System.out.println("I'm in line #" + 
    new Exception().getStackTrace()[0].getLineNumber());

С некоторыми подробностями:

StackTraceElement l = new Exception().getStackTrace()[0];
System.out.println(
    l.getClassName()+"/"+l.getMethodName()+":"+l.getLineNumber());

Это выведет что-то вроде этого:

com.example.mytest.MyClass/myMethod:103
24 голосов
/ 22 сентября 2008

Я вынужден ответить, не отвечая на ваш вопрос. Я предполагаю, что вы ищете номер строки исключительно для поддержки отладки. Есть лучшие способы. Есть хакерские способы получить текущую строку. Все, что я видел, медленно. Вам лучше использовать инфраструктуру ведения журналов, например, в пакете java.util.logging или log4j . Используя эти пакеты, вы можете настроить свою регистрационную информацию так, чтобы она включала контекст вплоть до имени класса. Тогда каждое сообщение журнала будет достаточно уникальным, чтобы знать, откуда оно пришло. В результате ваш код будет иметь переменную 'logger', которую вы вызываете через

logger.debug("a really descriptive message")

вместо

System.out.println("a really descriptive message")

14 голосов
/ 22 сентября 2008

Log4J позволяет вам включать номер строки как часть его шаблона вывода. См. http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html для получения подробной информации о том, как это сделать (ключевым элементом в шаблоне преобразования является «L»). Тем не менее, Javadoc включает в себя следующее:

ВНИМАНИЕ! Создание местоположения вызывающего абонента. информация очень медленная Это следует избегать использования, если исполнение скорость не проблема.

7 голосов
/ 12 апреля 2014

Я использую этот маленький метод, который выводит след и номер строки метода, который его вызвал.

 Log.d(TAG, "Where did i put this debug code again?   " + Utils.lineOut());

Дважды щелкните по выходу, чтобы перейти к этой строке исходного кода!

Возможно, вам придется настроить значение уровня в зависимости от того, куда вы положили свой код.

public static String lineOut() {
    int level = 3;
    StackTraceElement[] traces;
    traces = Thread.currentThread().getStackTrace();
    return (" at "  + traces[level] + " " );
}
7 голосов
/ 22 сентября 2008

Код, опубликованный @ simon.buchan, будет работать ...

Thread.currentThread().getStackTrace()[2].getLineNumber()

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

6 голосов
/ 22 сентября 2008

Я бы порекомендовал использовать инструментарий регистрации, такой как log4j . Ведение журнала настраивается через файлы свойств во время выполнения, и вы можете включать / выключать такие функции, как запись номера строки / имени файла.

Глядя на javadoc для PatternLayout , вы получите полный список опций - вам нужен% L.

0 голосов
/ 29 марта 2019

stackLevel зависит от глубины, которую вы вызываете этот метод. Вы можете попробовать от 0 до большого числа, чтобы увидеть, какая разница.

Если stackLevel допустимо, вы получите строку типа java.lang.Thread.getStackTrace(Thread.java:1536)

public static String getCodeLocationInfo(int stackLevel) {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        if (stackLevel < 0 || stackLevel >= stackTraceElements.length) {
            return "Stack Level Out Of StackTrace Bounds";
        }
        StackTraceElement stackTraceElement = stackTraceElements[stackLevel];
        String fullClassName = stackTraceElement.getClassName();
        String methodName = stackTraceElement.getMethodName();
        String fileName = stackTraceElement.getFileName();
        int lineNumber = stackTraceElement.getLineNumber();

        return String.format("%s.%s(%s:%s)", fullClassName, methodName, fileName, lineNumber);
}
0 голосов
/ 09 августа 2017

Ниже приведен проверенный код для строки регистрации без имени класса и имени метода, откуда вызывается метод регистрации

public class Utils {
/*
 * debug variable enables/disables all log messages to logcat
 * Useful to disable prior to app store submission
 */
public static final boolean debug = true;

/*
 * l method used to log passed string and returns the
 * calling file as the tag, method and line number prior
 * to the string's message
 */
public static void l(String s) {
    if (debug) {
        String[] msg = trace(Thread.currentThread().getStackTrace(), 3);
        Log.i(msg[0], msg[1] + s);
    } else {
        return;
    }
}

/*
 * l (tag, string)
 * used to pass logging messages as normal but can be disabled
 * when debug == false
 */
public static void l(String t, String s) {
    if (debug) {
        Log.i(t, s);
    } else {
        return;
    }
}

/*
 * trace
 * Gathers the calling file, method, and line from the stack
 * returns a string array with element 0 as file name and 
 * element 1 as method[line]
 */
public static String[] trace(final StackTraceElement e[], final int level) {
    if (e != null && e.length >= level) {
        final StackTraceElement s = e[level];
        if (s != null) { return new String[] {
                e[level].getFileName(), e[level].getMethodName() + "[" + e[level].getLineNumber() + "]"
        };}
    }
    return null;
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...