gpt4 book ai didi

Java反射之Call stack introspection详解

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Java反射之Call stack introspection详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

java是基于栈设计的语言,其实与c、c++语言相同。整个程序的运行表现在方法的执行是一系列入栈出栈的行为,栈是线程私有的.

在java语言中,我们可以跟踪方法的调用关系,即当前栈帧(栈顶)和已经入栈的栈帧的层次关系.

从java1.4以后,java语言的throwable类提供了以下方法:

?
1
2
3
4
5
6
7
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得到栈调用层级的关系、调用方法名及调用入口位置,代码示例:

Java反射之Call stack introspection详解

执行结果:

Java反射之Call stack introspection详解

调用结果显示的方法调用层级关系.

那我们得到这些信息有什么用呢.

1.日志:这些信息可以让应用的日志系统得到信息更详细.

2.安全:api可以决定调用者当前包或者类是否有权限进入.

3.流程控制:可以避免一些流程错误,比如无限递归调用.

实现一个简单的日志系统:

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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));
         }
     }
}

执行结果:

?
1
2
3
模拟打印日志: 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详解的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出.

原文链接:https://www.2cto.com/kf/201609/544142.html 。

最后此篇关于Java反射之Call stack introspection详解的文章就讲到这里了,如果你想了解更多关于Java反射之Call stack introspection详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com