溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java反射之Call stack introspection的示例分析

發(fā)布時(shí)間:2021-08-23 15:20:30 來源:億速云 閱讀:244 作者:小新 欄目:編程語言

小編給大家分享一下Java反射之Call stack introspection的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

java是基于棧設(shè)計(jì)的語言,其實(shí)與C、C++語言相同。整個(gè)程序的運(yùn)行表現(xiàn)在方法的執(zhí)行是一系列入棧出棧的行為,棧是線程私有的。

在java語言中,我們可以跟蹤方法的調(diào)用關(guān)系,即當(dāng)前棧幀(棧頂)和已經(jīng)入棧的棧幀的層次關(guān)系。

從java1.4以后,java語言的Throwable類提供了以下方法:

OpenDeclarationStackTraceElement[]java.lang.Throwable.getStackTrace()
ProvidesprogrammaticaccesstothestacktraceinformationprintedbyprintStackTrace().Returnsanarrayofstacktraceelements,eachrepresentingonestackframe.Thezerothelementofthearray(assumingthearray'slengthisnon-zero)representsthetopofthestack,whichisthelastmethodinvocationinthesequence.Typically,thisisthepointatwhichthisthrowablewascreatedandthrown.Thelastelementofthearray(assumingthearray'slengthisnon-zero)representsthebottomofthestack,whichisthefirstmethodinvocationinthesequence.
Somevirtualmachinesmay,undersomecircumstances,omitoneormorestackframesfromthestacktrace.Intheextremecase,avirtualmachinethathasnostacktraceinformationconcerningthisthrowableispermittedtoreturnazero-lengtharrayfromthismethod.Generallyspeaking,thearrayreturnedbythismethodwillcontainoneelementforeveryframethatwouldbeprintedbyprintStackTrace.Writestothereturnedarraydonotaffectfuturecallstothismethod.
Returns:
anarrayofstacktraceelementsrepresentingthestacktracepertainingtothisthrowable.
Since:
1.4

該方法返回的StackTraceElement[] 就是棧幀數(shù)組。數(shù)組下標(biāo)0的元素代表當(dāng)前棧頂棧幀,數(shù)組的最大下標(biāo)代表調(diào)用棧序列中第一個(gè)棧幀,也就是第一個(gè)方法的調(diào)用。我們可以從StackTraceElement得到棧調(diào)用層級(jí)的關(guān)系、調(diào)用方法名及調(diào)用入口位置,代碼示例:

Java反射之Call stack introspection的示例分析

執(zhí)行結(jié)果:

Java反射之Call stack introspection的示例分析

調(diào)用結(jié)果顯示的方法調(diào)用層級(jí)關(guān)系。

那我們得到這些信息有什么用呢。

1.日志:這些信息可以讓應(yīng)用的日志系統(tǒng)得到信息更詳細(xì)。

2.安全:API可以決定調(diào)用者當(dāng)前包或者類是否有權(quán)限進(jìn)入。

3.流程控制:可以避免一些流程錯(cuò)誤,比如無限遞歸調(diào)用。

實(shí)現(xiàn)一個(gè)簡(jiǎn)單的日志系統(tǒng):

package com.doctor.reflect;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
 * Call stack introspection
 * 
 * @author sdcuike
 *
 *     Created At 2016年8月29日 下午9:40:35
 */
public class CallStackIntrospectionDemo {
	private static final MyLogger logger = new LoggerImpl();
	public static void main(String[] args) {
		logger.logRecord("hello");
		IllegalArgumentException exception = new IllegalArgumentException("IllegalArgumentException");
		logger.logProblem("throwable", exception);
	}
	public interface MyLogger {
		// Types for log records
		int ERROR  = 0;
		int WARNING = 100;
		int STATUS = 200;
		int DEBUG  = 300;
		int TRACE  = 400;
		void logRecord(String message);
		void logProblem(String message, Throwable throwable);
	}
	public static class LoggerImpl implements MyLogger {
		@Override
		    public void logRecord(String message) {
			Throwable throwable = new Throwable();
			log(message, throwable.getStackTrace()[1]);
		}
		@Override
		    public void logProblem(String message, Throwable throwable) {
			StringWriter out = new StringWriter();
			PrintWriter writer = new PrintWriter(out);
			throwable.printStackTrace(writer);
			writer.flush();
			log(message + out.toString(), throwable.getStackTrace()[0]);
		}
		private void log(String message, StackTraceElement stackTraceElement) {
			String className = stackTraceElement.getClassName();
			String methodName = stackTraceElement.getMethodName();
			int lineNumber = stackTraceElement.getLineNumber();
			System.out.println(String.join(" ", "模擬打印日志:", methodName, className, "" + lineNumber, message));
		}
	}
}

執(zhí)行結(jié)果:

模擬打印日志: main com.doctor.reflect.CallStackIntrospectionDemo 36 hello
模擬打印日志: main com.doctor.reflect.CallStackIntrospectionDemo 38 throwablejava.lang.IllegalArgumentException: IllegalArgumentException
  at com.doctor.reflect.CallStackIntrospectionDemo.main(CallStackIntrospectionDemo.java:38)

上述日志,只是簡(jiǎn)單的在控制臺(tái)打印一些信息。

看完了這篇文章,相信你對(duì)“Java反射之Call stack introspection的示例分析”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI