62,614
社区成员
发帖
与我相关
我的任务
分享
public class Test{
public static void main(String[] args) {
test();
}
public static void printLine(String mess){
StackTraceElement[] stes = new Throwable().getStackTrace();
StackTraceElement tmp = stes[stes.length-2];
System.out.print( mess + ":" );
System.out.println( tmp );
System.out.println( tmp.getFileName() + tmp.getMethodName()
+ "(" + tmp.getFileName() + tmp.getLineNumber() + "): "
+ mess );
}
private static void test(){
printLine( "this is message" );
}
}
StackTraceElement[] trace = getOurStackTrace();
for (StackTraceElement traceElement : trace)
s.println("\tat " + traceElement);
可以发现这段代码就是下面显示 at 包.类.方法(文件:行号) 的代码, 那么我们看看 getOurStackTrace() 方法, 其中又有这么一段代码:
stackTrace = new StackTraceElement[depth];
for (int i=0; i < depth; i++)
stackTrace[i] = getStackTraceElement(i);
看完全部的代码后就会发现, 这段代码很明显就是获得行号的代码, 那么, 顺藤摸瓜, 看getStackTraceElement() 方法:
native StackTraceElement getStackTraceElement(int index);
再快得到真相的时候, 线索断了, 好吧, 我确实不知道是怎么得到行号的, 下面的是我根据其他东西猜出来的, lz不妨看看
首先, 我确实是第一次见native这个关键字, 所以查了一下, 发现这个关键字的作用是这样的:
更详细的信息lz可以自己查一下.
接下来, 我想到了javap,
我们可以看到, javap有一个参数,
这意味着什么?这应该就是在说.class文件中有行号信息吧, 不然怎么可能输出行号呢?
所以, 我写了一个及其怪异的java程序, 有时几个语句一行, 有时两个语句隔三四行, 然后使用javap命令反编译, 发现输出的行号完全正确, 那么这个时候可以相信.class文件是有行号信息了吧,
ok, 我们再说getStackTraceElement方法, 它既然不是用java写的, 而是用其他语言, 那么我们能不能猜测它其实是调用了java.exe(或者java.exe依赖的某个.dll文件)中的一个隐藏借口呢? 既然java程序是在java.exe上执行的(正常执行时), 那么执行堆栈应该也只有java.exe知道吧, 至于行号,java.exe完全可以从.class文件中读取, 那么, 我们猜测getStackTraceElement方法调用了java.exe中的某个隐藏借口也是可以的吧, 以上就是我的猜测...