欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

StackTraceElement获取方法调用栈信息实例详解

程序员文章站 2023-12-01 14:55:58
本文研究的主要是stacktraceelement获取方法调用栈信息的相关内容,具体介绍和实例如下。 一、什么是stacktrace stacktrace(堆栈轨迹)存...

本文研究的主要是stacktraceelement获取方法调用栈信息的相关内容,具体介绍和实例如下。

一、什么是stacktrace

stacktrace(堆栈轨迹)存放的就是方法调用栈的信息,异常处理中常用的printstacktrace()实质就是打印异常调用的堆栈信息。

二、stacktraceelement介绍

stacktraceelement表示stacktrace(堆栈轨迹)中的一个方法对象,属性包括方法的类名、方法名、文件名以及调用的行数。

public final class stacktraceelement implements java.io.serializable {
	// normally initialized by vm (public constructor added in 1.5) 
	private string declaringclass;
	private string methodname;
	private string filename;
	private int  linenumber;
}

stacktraceelement被定义为final,可见其作为一个java的基础类不允许被继承。

获取stacktraceelement的方法有两种,均返回stacktraceelement数组,也就是这个栈的信息。

1、thread.currentthread().getstacktrace()

2、new throwable().getstacktrace()

stacktraceelement数组包含了stacktrace(堆栈轨迹)的内容,通过遍历它可以得到方法间的调用过程,即可以得到当前方法以及其调用者的方法名、调用行数等信息

public class testclass {
	public static void main(string[] args) 
	  {
		new testclass().methoda();
	}
	private void methoda(){
		system.out.println("------进入methoda----------");
		methodb();
	}
	private void methodb(){
		system.out.println("------进入methodb----------");
		stacktraceelement elements[] = thread.currentthread().getstacktrace();
		for (int i = 0; i < elements.length; i++) {
			stacktraceelement stacktraceelement=elements[i];
			string classname=stacktraceelement.getclassname();
			string methodname=stacktraceelement.getmethodname();
			string filename=stacktraceelement.getfilename();
			int linenumber=stacktraceelement.getlinenumber();
			system.out.println("stacktraceelement数组下标 i="+i+",filename="
			          +filename+",classname="+classname+",methodname="+methodname+",linenumber="+linenumber);
		}
	}
}

三、用途

1、我们可以封装一个日志库,在打印目标日志的时候,也可以通过这个调用栈打印出这个日志所在的行数,这样就可以迅速的定位到日志输出行,再也不要全局搜索去查找了。

public static void d(string tag, string msg, object... params) {
  stacktraceelement targetstacktraceelement = gettargetstacktraceelement();
  log.d(tag, "(" + targetstacktraceelement.getfilename() + ":"
      + targetstacktraceelement.getlinenumber() + ")");
  log.d(tag, string.format(msg, params));
}

2、如果我们写了一个sdk,希望某个方法在固定的位置被调用,我们也可以在这个方法被调用的时候,进行检查,看这个方法的调用位置是否正确。

例如,必须在activity.onresume中执行,pvsdk.onresume,所以我们在调用pvsdk.onresume方法的时候,在pvsdk.onresume方法里面来通过获取调用栈的信息检测这个方法是否在activity的onresume方法中调用的。

public class pvsdk {
	public static void onresume() {
		stacktraceelement[] stacktrace = thread.currentthread().getstacktrace();
		boolean result = false;
		for (stacktraceelement stacktraceelement : stacktrace) {
			string methodname = stacktraceelement.getmethodname();
			string classname = stacktraceelement.getclassname();
			try {
				boolean assignablefromclass = class.forname(classname).isassignablefrom(activity.class);
				if (assignablefromclass && "onresume".equals(methodname)) {
					result = true;
					break;
				}
			}
			catch (classnotfoundexception e) {
			}
		}
		if (!result)
		      throw new runtimeexception("pvsdk.onresume must in activity.onresume");
	}
}

3、我们在进行源码分析的时候,如果想分析整个代码的执行流程,我们可以进行通过打印栈的信息来获取,这个在源码分析的时候还是挺有用的。

总结

以上就是本文关于stacktraceelement获取方法调用栈信息实例详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!