内联是由 Java 即时编译器执行的优化。
如果您有方法:
public int addPlusOne(int a, int b) {
return a + b + 1;
}
你这样称呼它:
public void testAddPlusOne() {
int v1 = addPlusOne(2, 5);
int v2 = addPlusOne(7, 13);
// do something with v1, v2
}
编译器可能会决定将函数调用替换为函数体,因此结果实际上如下所示:
public void testAddPlusOne() {
int v1 = 2 + 5 + 1;
int v2 = 7 + 13 + 1
// do something with v1, v2
}
编译器这样做是为了节省实际进行函数调用的开销,这将涉及将每个参数推送到堆栈上。
这显然只能用于非虚函数。考虑一下,如果在子类中重写了该方法,并且包含该方法的对象的类型在运行时之前未知,会发生什么情况...编译器如何知道要复制哪些代码:基类的方法体还是子类的方法体?由于在 Java 中,默认情况下所有方法都是虚拟的,因此您可以显式地将那些不能重写的方法标记为(或将它们放入类中)。这将有助于编译器确定该方法永远不会被重写,并且内联是安全的。(请注意,编译器有时也可以对非最终方法进行此确定。final
final
另外,请注意引号中的单词 may。最终方法不能保证是内联的。有多种方法可以保证方法不能内联,但无法强制编译器内联。无论如何,它几乎总是比你更清楚,因为内联将有助于而不是损害结果代码的速度。
请参阅维基百科,了解好处和问题的良好概述。