今日同时问我个问题:如果A类调用B类,通过反射机制能不能再B类获取到A类的调用方法名称和类名称
经网上查询[http://michael-paul.javaeye.com/blog/724857]得,不需要反射,通过Thread.getStackTrace()获取调用者堆栈信息。
getStackTrace
public StackTraceElement[] getStackTrace()
-
返回一个表示该线程堆栈转储的堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该序列中最新的方法调用。最后一个元素代表堆栈底,是该序列中最旧的方法调用。
如果有安全管理器,并且该线程不是当前线程,则通过 RuntimePermission("getStackTrace") 权限调用安全管理器的 checkPermission 方法,查看是否可以获取堆栈跟踪。
某些虚拟机在某些情况下可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,没有该线程堆栈跟踪信息的虚拟机可以从该方法返回一个零长度数组。
-
-
-
返回:
- StackTraceElement 数组,每个数组代表一个堆栈帧。
代码如下:
package other.thread;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StackTrace {
public void callMe(){
System.out.println("enter the method~");
whoCallMe();
}
public void whoCallMe(){
StackTraceElement stacks[]= Thread.currentThread().getStackTrace();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss,SS");
if(stacks == null || stacks.length<1){
return;
}
for(int i=stacks.length-1;i>=0;i--){
StackTraceElement stack = (StackTraceElement)stacks[i];
if(stack.getClassName().indexOf("java.lang.Thread")>=0){
continue;
}
System.out.println(sdf.format(new Date())+" [INFO] at "+stack.getClassName()+"."+stack.getMethodName()+" ("+stack.getFileName()+":"+stack.getLineNumber()+")");
}
}
}
调用代码:
package other.thread;
public class Test {
public static void main(String[] ben){
StackTrace st = new StackTrace();
st.callMe();
}
}
结果:
enter the method~
2011-03-22 03:35:50,234 [INFO] at other.thread.Test.main(Test.java:6)
2011-03-22 03:35:50,234 [INFO] at other.thread.StackTrace.callMe(StackTrace.java:9)
2011-03-22 03:35:50,234 [INFO] at other.thread.StackTrace.whoCallMe(StackTrace.java:13)