2008-09-22 2 views
114

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

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

+1

см @ недооцененным ответ Хуана ниже в течение короткого и сладкого однострочника! я просто отказался от 15 пунктов rep downvoting всех других ответов: v и upvoting Juan's – necromancer 2014-08-29 00:04:12

ответ

82

От Angsuman Chakraborty:

/** Get the current line number. 
* @return int - Current line number. 
*/ 
public static int getLineNumber() { 
    return Thread.currentThread().getStackTrace()[2].getLineNumber(); 
} 
+2

Это всегда будет возвращать номер строки оператора return в вызываемом методе и не обязательно номер строки вызова метода. – 2008-09-22 14:13:20

+0

Не получает ли [2] рамку над getLineNumber()? ([1] является getLineNumber() и [0], являющимся getStackTrace(), предположительно) – 2008-09-22 14:17:43

+1

Я немного поиграл, и если вы используете blah.getStackTrace [3] .getLineNumber() как тело метода, он возвращает номер строки где был вызван метод. – 2008-09-22 14:27:36

0

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

Вы хотели бы посмотреть на обогащении исключение в качестве метода для улучшения обработки исключений, http://tutorials.jenkov.com/java-exception-handling/exception-enrichment.html

7

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

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

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

0

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

24

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

logger.debug("a really descriptive message")

вместо

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

5

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

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

12

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

ПРЕДУПРЕЖДЕНИЕ Создание местоположения вызывающего абонента информация крайне медленная. Это следует избегать, если не выполняется .

0

первый общий метод (в полезности класса, в простом старом коде java1.4, хотя, возможно, придется переписать его для java1.5 и более)

/** 
* Returns the first "[class#method(line)]: " of the first class not equal to "StackTraceUtils" and aclass. <br /> 
* Allows to get past a certain class. 
* @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils. 
* @return "[class#method(line)]: " (never empty, because if aclass is not found, returns first class past StackTraceUtils) 
*/ 
public static String getClassMethodLine(final Class aclass) { 
    final StackTraceElement st = getCallingStackTraceElement(aclass); 
    final String amsg = "[" + st.getClassName() + "#" + st.getMethodName() + "(" + st.getLineNumber() 
    +")] <" + Thread.currentThread().getName() + ">: "; 
    return amsg; 
} 

Тогда конкретный метод полезности чтобы получить право stackElement:

/** 
    * Returns the first stack trace element of the first class not equal to "StackTraceUtils" or "LogUtils" and aClass. <br /> 
    * Stored in array of the callstack. <br /> 
    * Allows to get past a certain class. 
    * @param aclass class to get pass in the stack trace. If null, only try to get past StackTraceUtils. 
    * @return stackTraceElement (never null, because if aClass is not found, returns first class past StackTraceUtils) 
    * @throws AssertionFailedException if resulting statckTrace is null (RuntimeException) 
    */ 
    public static StackTraceElement getCallingStackTraceElement(final Class aclass) { 
    final Throwable   t   = new Throwable(); 
    final StackTraceElement[] ste  = t.getStackTrace(); 
    int index = 1; 
    final int limit = ste.length; 
    StackTraceElement st  = ste[index]; 
    String    className = st.getClassName(); 
    boolean aclassfound = false; 
    if(aclass == null) { 
     aclassfound = true; 
    } 
    StackTraceElement resst = null; 
    while(index < limit) { 
     if(shouldExamine(className, aclass) == true) { 
      if(resst == null) { 
       resst = st; 
      } 
      if(aclassfound == true) { 
       final StackTraceElement ast = onClassfound(aclass, className, st); 
       if(ast != null) { 
        resst = ast; 
        break; 
       } 
      } 
      else 
      { 
       if(aclass != null && aclass.getName().equals(className) == true) { 
        aclassfound = true; 
       } 
      } 
     } 
     index = index + 1; 
     st  = ste[index]; 
     className = st.getClassName(); 
    } 
    if(isNull(resst)) { 
     throw new AssertionFailedException(StackTraceUtils.getClassMethodLine() + " null argument:" + "stack trace should null"); //$NON-NLS-1$ 
    } 
    return resst; 
    } 

    static private boolean shouldExamine(String className, Class aclass) { 
     final boolean res = StackTraceUtils.class.getName().equals(className) == false && (className.endsWith(LOG_UTILS 
     ) == false || (aclass !=null && aclass.getName().endsWith(LOG_UTILS))); 
     return res; 
    } 

    static private StackTraceElement onClassfound(Class aclass, String className, StackTraceElement st) { 
     StackTraceElement resst = null; 
     if(aclass != null && aclass.getName().equals(className) == false) 
     { 
      resst = st; 
     } 
     if(aclass == null) 
     { 
      resst = st; 
     } 
     return resst; 
    } 
66

Мы закончили использовать специальный класс, как это для нашей 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); 
    } 
} 
} 
26

Быстрый и грязный способ:

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 
0

Посмотрите на this link. В этом методе вы можете перейти к вашему строковому коду, когда дважды щелкните по строке LogCat.

Также вы можете использовать этот код, чтобы получить номер строки:

public static int getLineNumber() 
{ 
    int lineNumber = 0; 
    StackTraceElement[] stackTraceElement = Thread.currentThread() 
      .getStackTrace(); 
    int currentIndex = -1; 
    for (int i = 0; i < stackTraceElement.length; i++) { 
     if (stackTraceElement[i].getMethodName().compareTo("getLineNumber") == 0) 
     { 
      currentIndex = i + 1; 
      break; 
     } 
    } 

    lineNumber = stackTraceElement[currentIndex].getLineNumber(); 

    return lineNumber; 
} 
0
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(Trace.class.getName())) { 
      break; 
     } 
    } 
    CLIENT_CODE_STACK_INDEX = i; 
} 

private String methodName() { 
    StackTraceElement ste=Thread.currentThread().getStackTrace()[CLIENT_CODE_STACK_INDEX+1]; 
    return ste.getMethodName()+":"+ste.getLineNumber(); 
} 
-1

Моего путь это работает для меня

String str = "select os.name from os where os.idos="+nameid; try { 
     PreparedStatement stmt = conn.prepareStatement(str); 
     ResultSet rs = stmt.executeQuery(); 
     if (rs.next()) { 
      a = rs.getString("os.n1ame");//<<<----Here is the ERROR   
     } 
     stmt.close(); 
    } catch (SQLException e) { 
     System.out.println("error line : " + e.getStackTrace()[2].getLineNumber());    
     return a; 
    } 
0

Они все получают вам номер строки вашего текущего потока и метод, который отлично работает, если вы используете try catch, где ожидаете исключения. Но если вы хотите поймать какое-либо необработанное исключение, вы используете обработчик исключенных исключений по умолчанию, а текущий поток будет возвращать номер строки функции обработчика, а не метод класса, создавший исключение. Вместо того, чтобы использовать Thread.currentThread() просто использовать Throwable, передаваемый в обработчик исключений:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
      public void uncaughtException(Thread t, Throwable e) {    
       if(fShowUncaughtMessage(e,t))    
        System.exit(1); 
      } 
     }); 

В вышеприведенном использовании e.getStackTrace() [0] в функции обработчика (fShowUncaughtMessage), чтобы получить преступник.

7

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

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] + " "); 
} 
-1

вы можете использовать -> Reporter.log ("");

0

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

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; 
} 
} 
Смежные вопросы