【转】StackTraceElement获取方法调用栈的信息
本文链接: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获取方法调用栈的信息的更多相关文章
- Linux下手动获取当前调用栈
被问到如何手动获取当前的调用栈,之前碰到过一时没记起来,现在回头整理一下. 其原理是:使用backtrace()从栈中获取当前调用各层函数调用的返回地址,backtrace_symbols()将对应地 ...
- Java中异常的处理以及自定义异常,抛出异常到方法调用栈底层
package com.gezhi; /** * 创建一个自定义异常SpendMoneyException类 * * @author square 凉 * */@SuppressWarnings(& ...
- JVM方法调用栈
摘自深入分析java web技术内幕
- 《浏览器工作原理与实践》<08>调用栈:为什么JavaScript代码会出现栈溢出?
在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript 引擎先会对其进行编译,并创建执行上下文.但是并没有明确说明到底什么样的代码才算符合规范. 那么接下来我们就来明确下,哪些情况下代码才 ...
- Windows下获取Dump文件以及进程下各线程调用栈的方法总结(转)
1. Dump文件的用途 Dump文件, 主要用于诊断一个进程的运行状态,尤其是碰到崩溃(Crash)或者挂起(hang)不响应时,需要分析它的工作状态. 除了平时常见的attach到这个进程, 分 ...
- 利用backtrace和backtrace_symbols函数打印调用栈信息
在头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈. #include <execinfo.h> int backtrace(void * ...
- java方法的理解、调用栈与异常处理
一.流程分支 If/else :基于boolean值的双分支 Switch:基于数字(整数.char.byte.枚举).字符串 类型的多分支 Int month =5; Switch 二.方法meth ...
- .NET使用StackTrace获取方法调用者信息
前言 在日常工作中,偶尔需要调查一些诡异的问题,而业务代码经过长时间的演化,很可能已经变得错综复杂,流程.分支众多,如果能在关键方法的日志里添加上调用者的信息,将对定位问题非常有帮助. 介绍 Stac ...
- 在C/C++程序里打印调用栈信息
我们知道,GDB的backtrace命令可以查看堆栈信息.但很多时候,GDB根本用不上.比如说,在线上环境中可能没有GDB,即使有,也不太可能让我们直接在上面调试.如果能让程序自己输出调用栈,那是最好 ...
随机推荐
- LB中使用到的一致性Hash算法的简单实现
1.类的Diagram 2.代码实现 2.1.Node类,每个Node代表集群里面的一个节点或者具体说是某一台物理机器: package consistencyhash; import lombok. ...
- 中国知网(cnki)上caj格式转pdf的方法 ----------------- 转载
原文地址: https://blog.csdn.net/edogawachia/article/details/85340636 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议 ...
- 带有Q_OBJECT的类要放在头文件的第一个类位置,否则可能无法moc
如果头文件中有多个类,带有Q_OBJECT的类要放在头文件的第一个类位置,否则可能无法moc
- yandex 图片自动下载
yandex 图片自动下载命令行程序 一个在 yandex 上搜索图片并下载到本地的 node cli 程序. 使用帮助: $0 <搜索关键词> [-t=超时(默认 1000)] [-r ...
- Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)
一.自定义控件大全 (一).控件介绍 超过160个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...
- 小程序报错:对应的服务器 TLS 为 TLS 1.0 ,小程序要求的 TLS 版本必须大于等于 1.2
我这里出现此错误的原因是,搭载域名网站的服务器是windows2008 r2,配置的域名证书是TLS1.0版本,需要在服务器注册表中加入TLS的其他版本. 处理办法如下 小程序报错 TLS 版本必须大 ...
- 安装 mysql-5.6.41-winx64
REF:https://www.cnblogs.com/cwb292/p/9888039.html https://dev.mysql.com/get/Downloads/MySQLInstaller ...
- php删除目录及目录下的内容
今天遇到一个问题: java写的API,ppt转图片生成的目录和文件 在使用php调用API完成后,再使用php进行删除时,遇到了删除失败的问题 部署的环境是Ubuntu 导致删除失败的原因是权限的问 ...
- 【视频开发】用GStreamer实现摄像头的采集和保存
GStreamer是流媒体软件的开发框架.可以这样说,在该框架的支持下,你可以非常简单地为很多格式的流媒体写出自已需要的程序. 现在,GStreamer已经内置对MP3.Ogg/Vorbis.MPEG ...
- scala 类,伴生对象
1.属性的定义 编写一个PersonS类,并在其中定义一些属性,通过PersonS.scala 编译后的情况查看,可以知道不同修饰符修饰的属性分别会生成什么方法(set,get) package co ...