- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
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得到栈调用层级的关系、调用方法名及调用入口位置,代码示例:
执行结果:
调用结果显示的方法调用层级关系.
那我们得到这些信息有什么用呢.
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的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在stackoverflow上查过很多类似的问题,比如call.call 1 , call.call 2 ,但我是新人,无法发表任何评论。我希望我能找到关于 JavaScript 解释器如何执行这些
“strace 是一个系统调用跟踪器,即一个调试工具,它打印出另一个进程/程序进行的所有系统调用的跟踪。”如果系统调用递归工作或一个系统调用调用另一个系统调用怎么办。我怎样才能得到这些信息? 可能的解
我的问题很简单:我正在将一个函数传递给其他一些稍后调用的函数(示例回调函数),问题是何时、为何以及最佳做法是什么。 样本:我有 xxx() 函数,我必须传递它,如下面的 window.onload 事
我是 Java 新手,我正在尝试学习 ScheduledExecutorService 接口(interface)。我在网上看到了下面的代码。 我没有看到任何对 Callable.call() 方法的
这是我的调用过程: System.out.println
在 typescript 中,我有一个 DataAccess 类,以便所有 Ajax 调用都通过单个对象进行路由,以节省应用程序中许多地方的代码重复。 在使用这种方法时,我需要使用回调将响应返回到调用
如何使用模拟来计算通过 call 或 apply 进行的函数调用 // mylib.js module.exports = { requestInfo: function(model, id) {
每次我尝试roxygenize 一个包我都会得到这个错误: Error: is.call(call) is not TRUE traceback() 的结果: 11: stop(sprintf(nge
这里如果我有一个记录“调用我的函数”的函数 function myFunction() { console.log('called my function') } Function.prototy
在 Javascript 中,Function.call() 可以在给定 this 值和零个或多个参数的情况下调用 Function。 Function.call 本身就是一个函数。所以理论上,Fun
这个问题已经有答案了: "object is not a function" when saving function.call to a variable (3 个回答) a is a functi
在调用 UITableView 上的 reloadData 方法后,我曾多次遇到此问题,但我不明白为什么? 这是一个问题,因为如果更新 TableView 的数据,tableview将不必要地查询不存
我继承了大约 400 行写得非常奇怪的 Fortran 77 代码,我正在尝试逐步分析它以使其在我的脑海中清晰。 无论如何,我有一个类似 header 的文件(实际上是一个 .h,但其中的代码是 fo
这是我的代码 class AuthAction(callbackUri:String) extends ActionBuilder[UserRequest] with ActionRefiner[
我继承了大约 400 行写得非常奇怪的 Fortran 77 代码,我正在尝试逐步分析它以使其在我的脑海中清晰。 无论如何,我有一个类似 header 的文件(实际上是一个 .h,但其中的代码是 fo
我知道这个问题之前在这里被问过 iOS 6 shouldAutorotate: is NOT being called .但我的情况有点不同。 最初,在应用程序启动时,我加载了一个 viewContr
我是 headfirst 设计模式的读者,我注意到了这一点。 “好莱坞原则,别叫我们,我们叫你” 这意味着高级组件告诉低级组件“不要调用我们,我们调用你” High-Level Component 是
这个问题在这里已经有了答案: Why does passing variables to subprocess.Popen not work despite passing a list of ar
我刚找到一个覆盖 OnPaintBackground 的表单。奇怪的是它从来没有被调用过!就像,完全一样。为什么是这样?表单被刷新、移动、调整大小等等,所以它应该一些重新绘制,对吧? 最佳答案 是否设
调用函数的方式 考虑这个简单的函数: function my(p) { console.log(p) } 我可以这样调用它: my("Hello"); 也像这样: my.call(this, "Hel
我是一名优秀的程序员,十分优秀!