java 基礎 通過封裝獲取運行時的類名及方法名的方法,深入淺出理解stackTraceElement

獲取方法名,通用

Thread.currentThread().getStackTrace()[1].getClassName()

非靜態方法獲取方法名

this.getClass().getName()

獲取類名

Thread.currentThread().getStackTrace()[1].getMethodName()

那麼接下來如果每次都要這麼用寫那麼多太累,所以封裝嘛,封裝可以幫助更好的理解

stackTraceElement[] 存放了一些 stackTraceElement,而StackTraceElement表示StackTrace(堆棧軌跡)中的一個方法對象,屬性包括方法的類名、方法名、文件名以及調用的行數。

Thread.currentThread()獲取系統當前運行的線程,getStackTrace()可以獲取java線程運行棧的信息。

一個線程運行棧的信息如下:首先棧是先進後出的,

入口類 StringTest 中 main() 方法,入棧

public class StringTest {

    public static void main(String[] args) {
        Test.me().print();
    }
}

緊接着 調用 Test類 me(), 入棧 隨後 調用 print() 入棧

public class Test{

    public static Test  me () {
        System.out.println(LogUtil.getLog());
        return new Test();
    }


    public void print () {
        System.out.println(LogUtil.getLog());
        System.out.println("this is  Test");
    }
}

調用 LogUtil log() ,入棧,實際打印出來的時候是沒有className()和methodName()的,如果在className和methodName中stackTraceElement下標爲2 會發現打印的是getLog,這也對應了下方的註釋數據,也就是實際還有一層,getLog調用className和methodName會在getLog調用之後 入棧。

最終是我們調用的getStackTrace() 入棧。

遵從先進後出的順序,我們從上到下下標依次從 0-n ,不難發現調用層數決定下標值,進一步理解java StackTraceElement對象

public class LogUtil {

    private static final String LOG_LEVEL = StringUtil.isBlank(Globals.LOG_LEVEL) ? Globals.DEFAULT_LOG_LEVEL : Globals.LOG_LEVEL; //默認LOG級別

    public static LogUtil me() {
        return new LogUtil();
    }

    public void log(Object log) {
        System.out.print("["+LOG_LEVEL+" ] "+getLog(2));
        System.out.println("\t"+String.valueOf(log == null ? "" : log));
    }

    private static String className(int i) {
        return Thread.currentThread().getStackTrace()[++i].getClassName();
    }

    private static String methodName(int i) {
        return Thread.currentThread().getStackTrace()[++i].getMethodName();
    }

    private static int lineNumber(int i) { return Thread.currentThread().getStackTrace()[++i].getLineNumber();}

    /**
     *
     * @return
     */
    public static String getLog() {
        return DateUtil.getNow()+"\t==>\t"+className(2)+":"+methodName(2);
    }

    public static String getLog(int i) {
        return DateUtil.getNow()+"\t==>\t"+className((i+1))+":("+methodName((i+1))+"."+lineNumber((i+1))+")";
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章