《java编程思想》中讲到final方法时提到,使用final方法原因有两个,
一、锁定方法。防止任何继承类修改、覆盖
二、效率。在java早期实现中,如果将一个方法指明为final,就是同意编译器将针对该方法的调用都转化为内嵌调用。…..
大概就是,如果是内嵌调用,虚拟机不再执行正常的方法调用(参数压栈,跳转到方法处执行,再调回,处理栈参数,处理返回值),而是直接将方法展开,以方法体重的实际代码替代原来的方法调用。这样减少了方法调用的开销。当然如果一个方法体本身就很大,这样的优势就小了很多了。
引用:函数/方法调用过程中CPU要进行现场处理(不妨看做是一种中断),当前的变量状态、寄存器状态、程序计数器PC。。。都要一一入栈保护起来,调用返回时又要一一出栈恢复以继续执行。相对于顺序执行流程,函数调用的入栈出栈带来了额外的开销,效率没有顺序执行高。
在最近的java设计中,虚拟机(特别是hotspot技术)可以自己去根据具体情况自动优化选择是否进行内联,因此和final关键字就无关了。
内联函数:
在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。
但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要非常注意的是对递归函数的内联扩展可能带来部分编译器的无穷编译。
C、C++中可以声明内联函数,在java中不支持直接声明,但是jvm会根据情况进行优化内联。
内联函数特点:
(1)提升效率。如上说明。
(2)占更多内存空间。编译器直接将内联函数扩展开,调用多复制品就多,因此更占用内存。
(3)java中不需额外关注,jvm会自动进行优化
内联举例:
int max (int a, int b){
if (a > b)
return a;
else
return b;
}
void main() {
.....
a = max (x, y); // 内联,等价于 "a = (x > y ? x : y);" 直接扩展开了,不再调用方法
.....
}