我们如何在java中将行号打印到日志中

Bob*_*mar 128 java logging

如何将行号打印到日志中.假设在向日志输出一些信息时,我还想打印输出在源代码中的行号.正如我们在堆栈跟踪中看到的,它显示发生异常的行号.异常对象上有堆栈跟踪.

其他替代方案可以是在打印到日志时手动包括行号.还有其他方法吗?

Sim*_*han 98

来自Angsuman Chakraborty:

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

  • 索引将根据JVM版本进行更改.我相信它从1.4变为1.5. (11认同)
  • 这将始终返回被调用方法中return语句的行号,而不一定是方法调用的行号. (4认同)
  • 这看起来很无辜,但我想知道“getStackTrace()”的成本是多少。看来下手很重啊。我希望有一个编译器解决方案/宏,可以在编译时对数字进行硬编码,就像 c++ 那样。尽管如此 - 这是最好的可用答案。 (4认同)
  • 那太奇怪了. (3认同)
  • 嘿@SimonBuchan,这家伙有个名字:)我早就写了那篇文章。 (2认同)

Mic*_*aks 71

我们最终在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);
  }
 }
}
Run Code Online (Sandbox Code Playgroud)

  • 在使用之前我会对这段代码做一些更多的研究 - 当我发布代码时,getStackTrace()[3]就可以了.它可能取决于Android或JVM的版本,或其他一些因素. (3认同)
  • 此答案不起作用,它显示行号以及DebugLog类的类名和函数名,而不是其他类的调用者的行号 (3认同)

Jua*_*uan 34

快速而肮脏的方式:

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

有一些更多细节:

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

这将输出如下内容:

com.example.mytest.MyClass/myMethod:103
Run Code Online (Sandbox Code Playgroud)


Jam*_*son 24

我不得不回答你的问题而回答.我假设您正在寻找仅用于支持调试的行号.有更好的方法.获得当前线路的方法有很多.我所看到的都很慢.最好使用java.util.logging包或log4j中的日志框架.使用这些程序包,您可以配置日志记录信息,以将上下文包含在类名中.然后每条日志消息都足够独特,以便知道它来自何处.因此,您的代码将具有您通过其调用的"记录器"变量

logger.debug("a really descriptive message")

代替

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


Jim*_*ley 14

Log4J允许您将行号作为其输出模式的一部分.有关如何执行此操作的详细信息,请参阅http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html(转换模式中的关键元素为"L").但是,Javadoc确实包含以下内容:

警告生成呼叫者位置信息非常慢.除非执行速度不是问题,否则应该避免使用它.


Ron*_*fin 7

@ simon.buchan发布的代码将有效...

Thread.currentThread().getStackTrace()[2].getLineNumber()
Run Code Online (Sandbox Code Playgroud)

但是如果你在方法中调用它,它将始终返回方法中行的行号,所以请使用内联代码片段.


Syd*_*ell 7

我使用这个小方法输出调用它的方法的跟踪和行号.

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

双击输出转到该源代码行!

您可能需要根据放置代码的位置调整级别值.

public static String lineOut() {
    int level = 3;
    StackTraceElement[] traces;
    traces = Thread.currentThread().getStackTrace();
    return (" at "  + traces[level] + " " );
}
Run Code Online (Sandbox Code Playgroud)


小智 6

我建议使用日志工具包,如log4j.日志记录可在运行时通过属性文件进行配置,您可以打开/关闭行号/文件名记录等功能.

查看PatternLayout的javadoc 可以获得完整的选项列表 - 你所追求的是%L.