« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9690316 建立时间:2004年12月20日 |

| |
[java语言]java程序如何知道自己被那个方法调用  原创空间, 文章收藏, 软件技术, 电脑与网络
邢红瑞 发表于 2010/11/25 17:37:34 |
根据以往的经验应该是跟踪堆栈信息,JDK 1.5 Thread提供 public StackTraceElement[] getStackTrace()
返回一个表示该线程堆栈转储的堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该序列中最新的方法调用。最后一个元素代表堆栈底,是该序列中最旧的方法调用。
如果有安全管理器,并且该线程不是当前线程,则通过 RuntimePermission("getStackTrace") 权限调用安全管理器的 checkPermission 方法,查看是否可以获取堆栈跟踪。
某些虚拟机在某些情况下可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,没有该线程堆栈跟踪信息的虚拟机可以从该方法返回一个零长度数组。
返回:
StackTraceElement 数组,每个数组代表一个堆栈帧。
抛出:
SecurityException - 如果安全管理器存在,并且其 checkPermission 方法不允许获取线程的堆栈跟踪。
StackTraceElement 有getClassName(), getFileName(), getLineNumber() 和getMethodName().
代码很简单
Utilities3.java
package test;
/** * Created by IntelliJ IDEA. * User: Administrator * Date: 2010-11-25 * Time: 17:18:37 * To change this template use File | Settings | File Templates. */public class Utilities3 { public static String getCurrentMethod() { return getCurrentMethodNameFromThread(0); }
public static String getCallingMethodName() { return getCurrentMethodNameFromThread(1); }
private static String getCurrentMethodNameFromThread(int stackLevel) { /* * 0 - dumpThreads * 1 - getStackTrace * 2 - thisMethod => getCurrentMethodNameFromThread * 3 - callingMethod => method calling thisMethod * 4 - method calling callingMethod */ StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2 + stackLevel];
String className = stackTraceElement.getClassName(); String methodName = stackTraceElement.getMethodName();
return className + "." + methodName; }}
如果是JDK 1.4 使用new Throwable()得到堆栈信息
Utilities2
package test;
import java.io.ByteArrayOutputStream;import java.io.PrintWriter;import java.util.StringTokenizer;
/** * Created by IntelliJ IDEA. * User: Administrator * Date: 2010-11-25 * Time: 17:17:21 * To change this template use File | Settings | File Templates. */public class Utilities2 { public static String getCurrentMethodName() { return getMethodName(0); }
public static String getCallingMethodName() { return getMethodName(1); }
private static String getMethodName(int stackLevel) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); PrintWriter printWriter = new PrintWriter(byteArrayOutputStream); (new Throwable()).printStackTrace(printWriter); printWriter.flush(); String stackTrace = byteArrayOutputStream.toString(); printWriter.close();
StringTokenizer stringTokenizer = new StringTokenizer(stackTrace, "\n"); String methodName = ""; for (int i = 0; i < stackLevel + 4; i++) { methodName = stringTokenizer.nextToken(); }
stringTokenizer = new StringTokenizer(methodName.trim(), " ("); stringTokenizer.nextToken(); methodName = stringTokenizer.nextToken();
return methodName; }}直接从堆栈中解析
Utilities
public class Utilities { public static String getCurrentMethodName() { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); PrintWriter printWriter = new PrintWriter(byteArrayOutputStream); (new Throwable()).printStackTrace(printWriter); printWriter.flush(); String stackTrace = byteArrayOutputStream.toString(); printWriter.close();
StringTokenizer stringTokenizer = new StringTokenizer(stackTrace, "\n");
// Line 1 -- java.lang.Throwable stringTokenizer.nextToken();
// Line 2 -- "at thisClass.thisMethod(file.java:line)" stringTokenizer.nextToken();
// Line 3 -- "at callingClass.callingMethod(file.java:line)" String methodName = stringTokenizer.nextToken(); stringTokenizer = new StringTokenizer(methodName.trim(), " ("); stringTokenizer.nextToken(); methodName = stringTokenizer.nextToken();
// Return callingClass.callingMethod return methodName; } }
测试 程序
package test;
/** * Created by IntelliJ IDEA. * User: Administrator * Date: 2010-11-25 * Time: 16:53:01 * To change this template use File | Settings | File Templates. */public class UtilitiesTest { public static void main(String[] args){ System.out.println("Method name: " + Utilities.getCurrentMethodName()); System.out.println("Method name: " + Utilities2.getCurrentMethodName()); System.out.println("Method name: " + Utilities3.getCallingMethodName()); }} |
|
|