在Java8中获取调用方方法的有效方法?
这就是我想要实现的:如果有一个方法在Java8中获取调用方方法的有效方法?,java,performance,exception,stack-frame,throwable,Java,Performance,Exception,Stack Frame,Throwable,这就是我想要实现的:如果有一个方法a()调用方法b(),我想知道是谁调用了方法b() public void a(){ b();//但它不一定在同一个类中 } 公共空间b(){ String方法=getCallerMethod();//返回“a” } 现在,使用StackWalkerAPI,可以在Java9+中高效地实现这一点。在Java8中,我可以使用Thread.currentThread().getStackTrace()或newException().getStackTrace(),但
a()
调用方法b()
,我想知道是谁调用了方法b()
public void a(){
b();//但它不一定在同一个类中
}
公共空间b(){
String方法=getCallerMethod();//返回“a”
}
现在,使用StackWalker
API,可以在Java9+中高效地实现这一点。在Java8中,我可以使用Thread.currentThread().getStackTrace()
或newException().getStackTrace()
,但这两种方法都非常慢。我不需要整个stacktrace,我只需要stacktrace中的前一帧,并且只需要该帧中的方法名(可能还有类名)
在Java 8中有没有有效的方法来实现这一点?您可以创建am异常并使用
fillInStacktrace()
,然后printStacktrace()
并粘贴结果
它的效率可能不太高,但如果只是为了调试,我不明白为什么需要这样做
(我不在电脑前,所以我没有试着编译它):
您可以创建am异常并使用
fillInStacktrace()
,然后printStacktrace()
并粘贴结果
它的效率可能不太高,但如果只是为了调试,我不明白为什么需要这样做
(我不在电脑前,所以我没有试着编译它):
SharedSecrets.getJavaLangAccess().getStackTraceDepth(e)
SharedSecrets.getJavaLangAccess().getStackTraceElement(e, index)
它有助于避免解码堆栈跟踪的巨大成本,但仍然需要收集整个跟踪。有关详细信息,请参阅
start\u depth
和max\u frame\u count
参数只允许获取堆栈跟踪的选定部分
这种方法的缺点是它需要一个本机库
我有一种使用GetStackTrace
的方法,它几乎可以满足您的需要:StackFrame.getLocation(depth)
方法只返回给定深度的一个堆栈帧
MethodHandles.lookup().lookupClass()
a
的所有invoke*
字节码,并将它们重写为使用调用方调用方法a\u(String callerMethod)
,其中callerMethod
参数是一个检测时间常数,从正在检测的方法派生
SharedSecrets.getJavaLangAccess().getStackTraceDepth(e)
SharedSecrets.getJavaLangAccess().getStackTraceElement(e, index)
它有助于避免解码堆栈跟踪的巨大成本,但仍然需要收集整个跟踪。有关详细信息,请参阅
start\u depth
和max\u frame\u count
参数只允许获取堆栈跟踪的选定部分
这种方法的缺点是它需要一个本机库
我有一种使用GetStackTrace
的方法,它几乎可以满足您的需要:StackFrame.getLocation(depth)
方法只返回给定深度的一个堆栈帧
MethodHandles.lookup().lookupClass()
a
的所有invoke*
字节码,并将它们重写为使用调用方调用方法a\u(String callerMethod)
,其中callerMethod
参数是一个检测时间常数,从正在检测的方法派生
除非这是测试/调试代码,否则其行为取决于调用它的人的函数是一个糟糕的设计。@user13784117,实际上,这是为了调试目的。tl;dr:不,没有有效的方法来实现这一点,因为JVM的许多优化都依赖于在代码流中可以忽略方法边界这一事实。显式检查调用者会破坏这些优化,并强制JVM执行去优化代码(或者在这种情况下显式优化的代码,如果它足够聪明的话)。请看@apangin,是的,我在提出问题之前已经看到了这一点,看起来非常好,并对其进行了测试,在我的例子中,它将时间减少了5倍,这很好,但我仍然希望进一步减少时间(如果可能的话),除非这是测试/调试代码,一个行为取决于调用它的人的函数是一个糟糕的设计。@user13784117,实际上,这是为了调试目的。tl;dr:不,没有有效的方法来实现这一点,因为JVM的许多优化都依赖于在代码流中可以忽略方法边界这一事实。显式检查调用者会破坏这些优化,并强制JVM执行去优化代码(或者在这种情况下显式优化的代码,如果它足够聪明的话)。请看@apangin,是的,我在提出问题之前已经看到了这一点,看起来非常好,并对其进行了测试,在我的例子中,它将时间减少了5倍,这很好,但我仍然想进一步减少它(如果可能的话),你能提供一个例子吗please@Nfff3当然,你能举个例子吗please@Nfff3当然可以,他补充道。谢谢,我会坚持解决方案4,还有更多的工作要做,但这是最有效的。谢谢,我将坚持解决方案4,还有更多的工作要做,但它是最有效的。