Java局部变量有没有final关键字对JVM性能影响不大
一.概述
在写Java代码中我们经常使用final这个关键字,被final修饰的变量,编译器不允许我们修改它的值,如果是基本类型,编译器不允许我们在第一次赋值后再修改基本类型的值,如果是引用类型,编译器不允许我们在第一次赋值后再修改引用的指向,这都是编译器层面的限制,因为如果你试图去修改它,就会得到一个编译错误。
二.如何证明final关键字对JVM的性能影响不大
我们写下面的Java代码
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 | public class FinalLocalVariableTest { public int generateInt() { return 3; } public int f1() { final int a = generateInt(); final int b = generateInt(); return a + b; } public int f2() { int a = generateInt(); int b = generateInt(); return a + b; } public int f3() { final int a = 2; final int b = 3; return a + b; } public int f4() { int a = 2; int b = 3; return a + b; } } |
上面的java代码很简单,我们分组来对比,首先看看f1和f2的写法,f1和f2的写法一样,只是在f1是使用了final类型的局部变量,但是在f2中没有使用final类型的局部变量,此时我们编译上面的代码后,使用javap -verbose来查看编译后f1和f2的字节码
红色框内的字节码表示局部变量量a,b的赋值
红四框内的字节码表示final类型局部变量a,b的赋值
对比发现,使用final关键字声明局部变量和不使用final关键子声明局部变量,生成的字节码都是一样的,对于JVM来说,最终执行的是字节码,既然字节码都一样,那么执行的性能也一样。
接下来我们看看f3和f4的字节码有何不同
观察上图,我们发现f3中使用了final关键字声明了局部变量a和b,此时a,b的值在编译阶段就能确定,因此字节码中直接返回常量5,但是f4中我们没有使用final关键字,因此先要把变量值load到方法栈上,然后执行变量的相加操作,最后返回相加的结果,不过这个对JVM的性能影响较小。
综上所述:
使用不使用final关键字修饰局部变量,对JVM的性能影响不大。