本文链接:https://blog.csdn.net/hp910315/article/details/52702199

一、什么是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获取方法调用者的具体信息

Android 从StackTraceElement反观Log库

【转】StackTraceElement获取方法调用栈的信息的更多相关文章

  1. Linux下手动获取当前调用栈

    被问到如何手动获取当前的调用栈,之前碰到过一时没记起来,现在回头整理一下. 其原理是:使用backtrace()从栈中获取当前调用各层函数调用的返回地址,backtrace_symbols()将对应地 ...

  2. Java中异常的处理以及自定义异常,抛出异常到方法调用栈底层

    package com.gezhi; /** * 创建一个自定义异常SpendMoneyException类 *  * @author square 凉 * */@SuppressWarnings(& ...

  3. JVM方法调用栈

    摘自深入分析java web技术内幕

  4. 《浏览器工作原理与实践》<08>调用栈:为什么JavaScript代码会出现栈溢出?

    在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript 引擎先会对其进行编译,并创建执行上下文.但是并没有明确说明到底什么样的代码才算符合规范. 那么接下来我们就来明确下,哪些情况下代码才 ...

  5. Windows下获取Dump文件以及进程下各线程调用栈的方法总结(转)

    1. Dump文件的用途 Dump文件, 主要用于诊断一个进程的运行状态,尤其是碰到崩溃(Crash)或者挂起(hang)不响应时,需要分析它的工作状态.  除了平时常见的attach到这个进程, 分 ...

  6. 利用backtrace和backtrace_symbols函数打印调用栈信息

    在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h>  int backtrace(void * ...

  7. java方法的理解、调用栈与异常处理

    一.流程分支 If/else :基于boolean值的双分支 Switch:基于数字(整数.char.byte.枚举).字符串 类型的多分支 Int month =5; Switch 二.方法meth ...

  8. .NET使用StackTrace获取方法调用者信息

    前言 在日常工作中,偶尔需要调查一些诡异的问题,而业务代码经过长时间的演化,很可能已经变得错综复杂,流程.分支众多,如果能在关键方法的日志里添加上调用者的信息,将对定位问题非常有帮助. 介绍 Stac ...

  9. 在C/C++程序里打印调用栈信息

    我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好 ...

随机推荐

  1. 阻止Bootstrap 模态框点击背景空白处自动关闭

    问题描述 模态框点击空白处,会自动关闭,怎么阻止关闭事件呢? 解决方法 在HTML页面中编写模态框时,在div初始化时添加属性 aria-hidden=”true” data-backdrop=”st ...

  2. vue form表单上传文件

    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js">< ...

  3. 前端文章索引:HTML+CSS+JS

    1 HTML 1.1 HTML5 HTML5 – 1.基础 HTML5 – 2.新元素 HTML5 – 3.加强版ol HTML5 – 4.canvas 2 CSS 2.1 CSS3 CSS3–1.c ...

  4. tensorflow 笔记 15:如何使用 Supervisor

    如何使用Supervisor在不使用Supervisor的时候,我们的代码经常是这么组织的 variables ... ops ... summary_op ... merge_all_summari ...

  5. Kafka高级设计和架构,一文深化理解

    主题: 1.kafka是写磁盘还是写内存? 2.kafka究竟是由 consumer 从 broker 那里拉数据,还是由 broker 将数据推到 consumer? 3.如何区分已消费(consu ...

  6. HTML和CSS个人笔记

    目录 定位 文字显示在图片上 ul的li元素的小圆点换成图片 关于Bootstrap的响应式 不要在container之外使用row 不要使用padding的时候固定高度 不要使用<hr p标签 ...

  7. [Tool] Give some magic ! 那些奇思妙想的 Chrome 插件

    [ Reggy ] - 网站注册类自动填充临时信息,Magic! 但是对于非常规的网站无效.是什么意思呢? 就是说,它不是常规的 form 表单,而是使用 Js 操作数据,所以任何插件都无法自动识别. ...

  8. Postman 设置变量

  9. replace的回调函数。

    今天在看算法时,看到一些题目,感觉replace的回调函数好奇葩,$0 .$1什么的: JS的replace方法: str.replace(regexp|substr, newSubStr|funct ...

  10. Website Scraping with Python 阅读笔记

    第一章 工程涉及的基本工具:requests, beautiful soup, scrapy. 法规与技术约定:read the Terms & Conditions and the Priv ...