java 日志 行号_Java代码中如何获文件名和行号等源码信息?

C语言中有__FILE__、__LINE__等预定义宏,用于获取当前文件名和行号等信息,而且它们的值在预处理时就已经确定了,不会占用运行时时间去计算,这对打印日志相当有用。那么,Java语言是否也有类似的功能呢?

Java是否提供某种方法:可以让用户代码在编译时确定源码行号等信息,本人暂时不知晓。不过从网上搜索得到的方法大致是:

Thread.currentThread().getStackTrace()[1].getFileName():获取当前文件名;

Thread.currentThread().getStackTrace()[1].getLineNumber():获取当前行号。

其中:Thread.currentThread().getStackTrace()返回的是一个数组形式的函数调用栈(栈顶在索引0处),其中第1个元素(索引为0)为最新调用的函数信息(getStackTrace()),第2个元素(索引为1)为当前函数(即调用getStackTrace()的函数)信息。示例:

1 public classTest {2 public static voidmain(String args[]) {3 StackTraceElement[] stack =Thread.currentThread().getStackTrace();4 for (int i = 0; i < stack.length; ++i)5 System.out.println(stack[i].getFileName() + ":" + stack[i].getLineNumber() + ": " +stack[i].getMethodName());6 System.out.println("");7 foo();8 }9 static voidfoo() {10 StackTraceElement[] stack =Thread.currentThread().getStackTrace();11 for (int i = 0; i < stack.length; ++i)12 System.out.println(stack[i].getFileName() + ":" + stack[i].getLineNumber() + ": " +stack[i].getMethodName());13 System.out.println("");14 bar();15 }16 static voidbar() {17 StackTraceElement[] stack =Thread.currentThread().getStackTrace();18 for (int i = 0; i < stack.length; ++i)19 System.out.println(stack[i].getFileName() + ":" + stack[i].getLineNumber() + ": " +stack[i].getMethodName());20 }21 }

输出:

$ javac Test.java

$ java Test

null:-1: getStackTrace

Test.java:3: main

null:-1: getStackTrace

Test.java:10: foo

Test.java:7: main

null:-1: getStackTrace

Test.java:17: bar

Test.java:14: foo

Test.java:7: main

于是,如果我们想在日志中打印当前文件名和行号,就可以:

1 public classTest {2 public static voidmain(String args[]) {3 System.out.println(Thread.currentThread().getStackTrace()[1].getFileName() + ":" + Thread.currentThread().getStackTrace()[1].getLineNumber());4 foo();5 }6 static voidfoo() {7 System.out.println(Thread.currentThread().getStackTrace()[1].getFileName() + ":" + Thread.currentThread().getStackTrace()[1].getLineNumber());8 bar();9 }10 static voidbar() {11 System.out.println(Thread.currentThread().getStackTrace()[1].getFileName() + ":" + Thread.currentThread().getStackTrace()[1].getLineNumber());12 }13 }

输出:

$ javac Test.java

$ java Test

Test.java:3

Test.java:7

Test.java:11

不过每次都要写这么长的几串代码“Thread.currentThread().getStackTrace()[1].getXXX()”拼一起看起来难看敲起来也累。于是我们可以将getStackTrace()封装到另一个函数中:

1 public classTest {2 public static voidmain(String args[]) {3 System.out.println(__FILE__() + ":" +__LINE__());4 foo();5 }6 static voidfoo() {7 System.out.println(__FILE__() + ":" +__LINE__());8 bar();9 }10 static voidbar() {11 System.out.println(__FILE__() + ":" +__LINE__());12 }13 staticString __FILE__() {14 return Thread.currentThread().getStackTrace()[2].getFileName();15 }16 static int__LINE__() {17 return Thread.currentThread().getStackTrace()[2].getLineNumber();18 }19 }

输出结果一样:

$ javac Test.java

$ java Test

Test.java:3

Test.java:7

Test.java:11

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值