小编给大家分享一下Java反射之Call stack introspection的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!java是基于栈设计的语言,其实与C、c++语言相同。整个程序的运行表现在方法的执行是
小编给大家分享一下Java反射之Call stack introspection的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
java是基于栈设计的语言,其实与C、c++语言相同。整个程序的运行表现在方法的执行是一系列入栈出栈的行为,栈是线程私有的。
在java语言中,我们可以跟踪方法的调用关系,即当前栈帧(栈顶)和已经入栈的栈帧的层次关系。
从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[] 就是栈帧数组。数组下标0的元素代表当前栈顶栈帧,数组的最大下标代表调用栈序列中第一个栈帧,也就是第一个方法的调用。我们可以从StackTraceElement得到栈调用层级的关系、调用方法名及调用入口位置,代码示例:
执行结果:
调用结果显示的方法调用层级关系。
那我们得到这些信息有什么用呢。
日志:这些信息可以让应用的日志系统得到信息更详细。
流程控制:可以避免一些流程错误,比如无限递归调用。
实现一个简单的日志系统:
package com.doctor.reflect;import java.io.PrintWriter;import java.io.StringWriter;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 recordsint 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));}}}
执行结果:
模拟打印日志: 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)
上述日志,只是简单的在控制台打印一些信息。
看完了这篇文章,相信你对“Java反射之Call stack introspection的示例分析”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网精选频道,感谢各位的阅读!
--结束END--
本文标题: Java反射之Call stack introspection的示例分析
本文链接: https://lsjlt.com/news/221455.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
2024-05-24
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0