浅谈getStackTrace()方法(一)
缘起:
今天看到有一个工具类中有一句:
String msgToPrint = Thread.currentThread().getStackTrace()[1].getMethodName();
输出的结果很简单,就是调用类的方法名。
文档:
public StackTraceElement[] getStackTrace()
- 返回一个表示该线程堆栈转储的堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该序列中最新的方法调用。最后一个元素代表堆栈底,是该序列中最旧的方法调用。
如果有安全管理器,并且该线程不是当前线程,则通过 RuntimePermission("getStackTrace") 权限调用安全管理器的 checkPermission 方法,查看是否可以获取堆栈跟踪。
某些虚拟机在某些情况下可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,没有该线程堆栈跟踪信息的虚拟机可以从该方法返回一个零长度数组。
- 返回:
- StackTraceElement 数组,每个数组代表一个堆栈帧。
其中使用的Thread类的第一个方法:
public static Thread currentThread()
第二个方法:(阅读Java SE的文档:)
public StackTraceElement[] getStackTrace()
返回一个堆栈轨迹元素的数组,代表了这个线程的堆栈情况。
如果:1.这个线程没有被开启;2.这个线程被开启了但是没有被系统运行过(因为线程运行是需要根据一定规律轮换的);3.这个线程结束了。
这三种情况下getStackTrace()返回的数组长度为0。
如果返回的数组长度不为0,那么数组的第一个元素代表栈顶元素,即是这个调用序列中最recent的方法。
数组的最后一个元素代表栈底元素,即调用序列中最远的一个元素。
程序实测——Java程序
测试类,main方法如下:
public static void main(String[] args) {
StackTraceElement[] stackTraceElements=Thread.currentThread().getStackTrace();
System.out.println("The stackTraceElements length:"+stackTraceElements.length);
for(int i=0;i<stackTraceElements.length;i++){
System.out.println("\n---the "+i+" element"+"---");
System.out.println("toString:"+stackTraceElements[i].toString());
System.out.println("ClassName:"+stackTraceElements[i].getClassName());
System.out.println("FileName:"+stackTraceElements[i].getFileName());
System.out.println("LineNumber:"+stackTraceElements[i].getLineNumber());
System.out.println("MethodName:"+stackTraceElements[i].getMethodName());
}
}
执行后输出:
The stackTraceElements length:2 ---the 0 element---
toString:java.lang.Thread.getStackTrace(Thread.java:1567)
ClassName:java.lang.Thread
FileName:Thread.java
LineNumber:1567
MethodName:getStackTrace ---the 1 element---
toString:Exchange.main(Exchange.java:10)
ClassName:Exchange
FileName:Exchange.java
LineNumber:10
MethodName:main
如果再用一个私有方法,输出调用堆栈的信息
public static void main(String[] args) {
StackTraceElement[] stackTraceElements=Thread.currentThread().getStackTrace();
System.out.println("The stackTraceElements length:"+stackTraceElements.length);
for(int i=0;i<stackTraceElements.length;i++){
System.out.println("\n---the "+i+" element"+"---");
System.out.println("toString:"+stackTraceElements[i].toString());
System.out.println("ClassName:"+stackTraceElements[i].getClassName());
System.out.println("FileName:"+stackTraceElements[i].getFileName());
System.out.println("LineNumber:"+stackTraceElements[i].getLineNumber());
System.out.println("MethodName:"+stackTraceElements[i].getMethodName());
}
printStackInfos();
}
private static void printStackInfos(){
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
System.out.println("\nCalled in printStackInfos() method!!!");
System.out.println("The stackTraceElements length:"+stackTraceElements.length);
for(int i =0;i<stackTraceElements.length;i++){
System.out.println("\n---the "+i+" element"+"---");
System.out.println("toString:"+stackTraceElements[i].toString());
System.out.println("ClassName:"+stackTraceElements[i].getClassName());
System.out.println("FileName:"+stackTraceElements[i].getFileName());
System.out.println("LineNumber:"+stackTraceElements[i].getLineNumber());
System.out.println("MethodName:"+stackTraceElements[i].getMethodName());
}
}
则输出结果如下:
The stackTraceElements length:2 ---the 0 element---
toString:java.lang.Thread.getStackTrace(Thread.java:1567)
ClassName:java.lang.Thread
FileName:Thread.java
LineNumber:1567
MethodName:getStackTrace ---the 1 element---
toString:Exchange.main(Exchange.java:10)
ClassName:Exchange
FileName:Exchange.java
LineNumber:10
MethodName:main Called in printStackInfos() method!!!
The stackTraceElements length:3 ---the 0 element---
toString:java.lang.Thread.getStackTrace(Thread.java:1567)
ClassName:java.lang.Thread
FileName:Thread.java
LineNumber:1567
MethodName:getStackTrace ---the 1 element---
toString:Exchange.printStackInfos(Exchange.java:24)
ClassName:Exchange
FileName:Exchange.java
LineNumber:24
MethodName:printStackInfos ---the 2 element---
toString:Exchange.main(Exchange.java:20)
ClassName:Exchange
FileName:Exchange.java
LineNumber:20
MethodName:main
可以看到加了一个私有方法之后,返回的堆栈元素就多了一个,并且它的位置在调用它的方法和被它调用的方法之间。
浅谈getStackTrace()方法(一)的更多相关文章
- 浅谈 虚方法(virtual)
虚方法 理解:从字面意思来讲,"虚",可有可无,子类对父类的某种方法的重写,可以重写,也可以不重写. 虚方法,顾名思义(装个13),就是某种方法. 用法:public virtua ...
- 浅谈getResource方法
项目经常会读取一些配置文件, 因此getResource方法便能够起到重要作用 使用时主要是两种方法, 一个是字节码文件Class类, 另一个是ClassLoader类加载器 使用Class类时有两种 ...
- Python之浅谈绑定方法
目录 绑定方法和非绑定方法 绑定方法 对象的绑定方法 类的绑定方法 非绑定方法 总结 绑定方法和非绑定方法 类中定义的方法大致可以分为两类:绑定方法和非绑定方法.其中绑定方法又可以分为绑定到对象的方法 ...
- 浅谈Android应用保护(一):Android应用逆向的基本方法
对于未进行保护的Android应用,有很多方法和思路对其进行逆向分析和攻击.使用一些基本的方法,就可以打破对应用安全非常重要的机密性和完整性,实现获取其内部代码.数据,修改其代码逻辑和机制等操作.这篇 ...
- JavaScript中toStirng()与Object.prototype.toString.call()方法浅谈
toStirng()与Object.prototype.toString.call()方法浅谈 一.toString()是一个怎样的方法?它是能将某一个值转化为字符串的方法.然而它是如何将一个值从一种 ...
- 浅谈配置chrome浏览器允许跨域操作的方法
浅谈配置chrome浏览器允许跨域操作的方法 一:(Lying人生感悟.可忽略) 最近有一天,对着镜子,发现满脸疲惫.脸色蜡黄.头发蓬松.眼神空洞,于是痛诉着说生活的不如意,工作没激情,工资不高,一个 ...
- 【转】浅谈Java中的hashcode方法(这个demo可以多看看)
浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...
- 浅谈局域网ARP攻击的危害及防范方法(图)
浅谈局域网ARP攻击的危害及防范方法(图) 作者:冰盾防火墙 网站:www.bingdun.com 日期:2015-03-03 自 去年5月份开始出现的校内局域网频繁掉线等问题,对正常的教育教 ...
- [原创]浅谈NT下Ring3无驱进入Ring0的方法
原文链接:浅谈NT下Ring3无驱进入Ring0的方法 (测试环境:Windows 2000 SP4,Windows XP SP2.Windows 2003 未测试) 在NT下无驱进入Ring0是一个 ...
随机推荐
- Spark Job具体的物理执行
即使采用pipeline的方式,函数f对依赖的RDD中的数据集合的操作也会有两种方式: 1.f(record),f作用于集合的每一条记录,每次只作用于一条记录 2.f(records),f一次性作用于 ...
- mysql grant 用户权限说明
mysql grant 用户权限说明 Mysql 有多个个权限?经常记不住,今天总结一下,看后都能牢牢的记在心里啦!! 很明显总共28个权限:下面是具体的权限介绍:转载的,记录一下: 一.权限表 my ...
- shell时间变量拼接问题
shell时间变量拼接问题 例1 ABC=ABC_`date –date='yesterday' "+%Y%m%d"`
- C# 使用Epplus导出Excel [4]:合并指定行
C# 使用Epplus导出Excel [1]:导出固定列数据 C# 使用Epplus导出Excel [2]:导出动态列数据 C# 使用Epplus导出Excel [3]:合并列连续相同数据 C# 使用 ...
- Python函数的基本定义和调用以及内置函数
首先我们要了解Python函数的基本定义: 函数是什么? 函数是可以实现一些特定功能的小方法或是小程序.在Python中有很多内建函数,当然随着学习的深入,你也可以学会创建对自己有用的函数.简单的理解 ...
- Python学习笔记:面向对象(类)
1.类定义:Python3中,如果新建的类没有继承任何其他类,默认继承基础类object.Python2中如果没有显式继承object类就是经典类,而显式继承了object类就是新式类,Python2 ...
- redis列表,字典,管道,vue安装,创建项目
redis mysql,redis,mogondb 1.mysql,oracle:关系型数据库,有表概念 2.redis,mongodb/nosql:非关系型数据库 没有表概念 mongodb存储在硬 ...
- HTTP认证之基本认证——Basic(二)
导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 在HTTP认证 ...
- Linux学习-Tarball 的管理与建议
使用原始码管理软件所需要的基础软件 从原始码的说明我们晓得要制作一个 binary program 需要很多咚咚的呢!这包括底下这些基础的软件: gcc 或 cc 等 C 语言编译程序 (compil ...
- Monkey与MonkeyRunner之间的区别
为了支持黑盒自动化测试的场景,Android SDK提供了monkey和monkeyrunner两个测试工具,这两个测试工具除了名字类似外,还都可以向待测应用发送按键等消息,往往容易产生混淆,以下是他 ...