Java线程运行轨迹-代码追踪与定位

简介: 今天在写程序时,想到一个问题,当我的程序出异常的时候,控制台输出信息中,明确指出了出现异常的位置,并详细列举了函数的调用层次关系,它是怎么做到的。 竟然想到了这个问题,就去查看了源代码,不过没点几下,就遇到了native本地方法,只好作罢。

今天在写程序时,想到一个问题,当我的程序出异常的时候,控制台输出信息中,明确指出了出现异常的位置,并详细列举了函数的调用层次关系,它是怎么做到的。

竟然想到了这个问题,就去查看了源代码,不过没点几下,就遇到了native本地方法,只好作罢。于是又去网上找了这方面的资料,最后找到了一点这方面的东西,不过它给出的只是API,却并没有对代码做什么解释。代码如下


public class Test {
	public static int getLineNumber() {
		return Thread.currentThread().getStackTrace()[2].getLineNumber();
	}

	public static String getFileName() {
		return Thread.currentThread().getStackTrace()[2].getFileName();
	}

	public static void main(String args[]) {
		System.out.println("[" + getFileName() + ":" + getLineNumber() + "]" + "Hello World!");
	}
}

这程序中为什么要取数组中的第二个呢?原帖没有给出解释。

接着,我自己去写了一段代码进行测试,代码如下

class StackTraceDemo
{
	public static void main(String[] args) 
	{
		System.out.println(findLocation(2));
		System.out.println();
		System.out.println(findAllLocation());
	}

	public static String findAllLocation()
	{
		StringBuilder locations = new StringBuilder();
		StackTraceElement elements [] = Thread.currentThread().getStackTrace();

		for(int i=0;i<elements.length;i++){
			locations.append(findLocation(i) +"\n");
		}
	
		return locations.toString();
	}
	
	public static String findLocation(int level)
	{
		StackTraceElement element = Thread.currentThread().getStackTrace()[level];
		return "File: "+element.getFileName()+" Line: "+element.getLineNumber()+" Method: "+element.getMethodName();
	}
}

程序运行得到这样的结果:

File: StackTraceDemo.java Line: 5 Method: main


File: Thread.java Line: 1567 Method: getStackTrace
File: StackTraceDemo.java Line: 24 Method: findLocation
File: StackTraceDemo.java Line: 16 Method: findAllLocation


从这个结果中来看,之所以前面那个程序选取第二个元素,是因为Java程序运行时函数入栈是在数组的起始位置入栈,其它的栈元素后移。这是我的个人之见,我也不敢确定自己所想是否正确,欢迎有别的看法的人或知道原理的人留言指点交流。


目录
相关文章
|
5月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
456 6
|
5月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
319 115
|
5月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
232 98
|
5月前
|
Java 编译器 API
java最新版和java8的区别,用代码展示
java最新版和java8的区别,用代码展示
463 43
|
5月前
|
Java 测试技术 API
【JUC】(1)带你重新认识进程与线程!!让你深层次了解线程运行的睡眠与打断!!
JUC是什么?你可以说它就是研究Java方面的并发过程。本篇是JUC专栏的第一章!带你了解并行与并发、线程与程序、线程的启动与休眠、打断和等待!全是干货!快快快!
848 2
|
5月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
278 1
|
5月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
299 1
|
5月前
|
安全 Java 容器
告别空指针噩梦:Optional让Java代码更优雅
告别空指针噩梦:Optional让Java代码更优雅
466 94
|
5月前
|
安全 Java 容器
告别繁琐判空:Optional让你的Java代码更优雅
告别繁琐判空:Optional让你的Java代码更优雅
|
6月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
799 3

热门文章

最新文章