先来看下面这句代码:
String msgToPrint = Thread.currentThread().getStackTrace()[3] .getMethodName();
输出的结果很简单,就是调用时的方法名。
其中使用的Thread类的第一个方法:
public static Thread currentThread()
返回当前线程对象。
第二个方法:(阅读Java SE的文档)
public StackTraceElement[] getStackTrace()
返回一个堆栈轨迹元素的数组,代表了这个线程的堆栈情况。
如果发生以下三种情况下,getStackTrace()返回的数组长度为0
- 这个线程没有被开启;
- 这个线程被开启了但是没有被系统运行过(因为线程运行是需要根据一定规律轮换的)
- 这个线程结束了。
如果返回的数组长度不为0,那么数组的第一个元素代表栈顶元素,即是这个调用序列中最recent的方法。数组的最后一个元素代表栈底元素,即调用序列中最远的一个元素。
我们写个Android代码测试一下:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//用一个私有方法,输出调用堆栈的信息
printStackInfos();
}
private void printStackInfos() {
StackTraceElement[] stackTraceElements = Thread.currentThread()
.getStackTrace();
System.out.println("Called in printStackInfos() method!!!!!!!");
System.out.println("The stackTraceElements length: "
+ stackTraceElements.length);
for (int i = 0; i < stackTraceElements.length; ++i) {
System.out.println("---- 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());
}
}
}
输出结果
可以清楚地看到,当获取stack trace的语句放在另一个方法(工具类方法)中的时候,数组索引为3的元素可以找到该工具类方法的调用地点。
在此例中,找到的是onCreate()方法中的第12行。