考虑以下代码:
Optional<Method> method = Arrays.stream(clazz.getMethods()).filter(m -> m.getName().equals("hello")).findFirst();
if (method.isPresent()) {
method.get().invoke(instance);
}
在 IntelliJ IDEA 中单步调试(调试)上面的
invoke
方法时,我发现自己处于方法 java.lang.reflect.Method.invoke
中。但是对于以下(略有更改)代码:
Optional<Method> method = Arrays.stream(clazz.getMethods()).filter(m -> m.getName().equals("hello")).findFirst();
if (method.isPresent()) {
Method m = method.get();
m.invoke(instance);
}
我将直接进入
<instance>.hello
方法(这是我真正想要的)。唯一的区别是 method.get().invoke(instance)
被分成两个调用。
有人可以解释这种奇怪的不同行为吗?
产生差异的原因在于调试器处理内联的方式。 在第一个示例中,
method.get().invoke(instance)
被视为一个复合操作,因此调试器在 Method.invoke
处停止。在第二个示例中,拆分调用让调试器直接将 m.invoke(instance)
与目标方法 (hello) 相关联,因此它会按预期步入 hello。
关于方法内联,您可以阅读以下内容:什么是方法内联?
编译器可以通过用函数本身的实际代码替换函数调用来优化性能,从而降低运行时调用函数的成本。