无继承
有 static 修饰
static final
static 非 final
结果
这里使用了 OpenJDK 的 JMH 基准测试工具来测试的,结果如下:
总结:你说final的性能比非final有没有提升呢?可以说有,但几乎可以忽略不计。如果单纯地追求性能,而将所有的方法修改为 final 的话,我认为这样子是不可取的。而且这性能的差别,远远也没有网上有些人说的提升 50% 这么恐怖(有可能他们使用的是10年前的JVM来测试的吧^_^,比如 《35+ 个 Java 代码性能优化总结》这篇文章。雷总:不服?咱们来跑个分!)
分析
字节码级别的差别
StringKit.java
StringKitFinal.java
它们在字节码上的差别:
可以看到除了方法名和方法修饰符不同之外,其他的没有什么区别了。
在调用者上面的字节码差别
可以看到,它们在调用者上面的字节码也没有什么区别,只是方法名不一样之外。
对于 JVM 来说,它是只认字节码的,既然字节码除了方法名和修饰符一样,其他都一样,那就可以大概推测它们的性能几乎可以忽略不计了。因为调用 static final 和 static 非 final 的JVM指令是一样。
无 static 修饰
方法体是一样的,只是将它们删除了 static 的修饰。
结果
分析
字节码级别的差别
可以看到,字节码上除了名字和 final 修饰符差别外,其余的是一样的。
在调用者上面的字节码差别
可以看到,它们除了名字不同之外,其他的JVM指令都是一样的。
总结
对于是否有 final 修饰的方法,对性能的影响可以忽略不计。因为它们生成的字节码除了 flags 标志位是否有 final 修饰不同之外,其他所有的JVM指令,都是一样的(对于方法本身,以及调用者本身的字节码都一样)。对于JVM来说,它执行的就是字节码,如果字节码都一样的话,那对于JVM来说,它就是同一样东西的了。
有继承
无 final 修饰
有 final 修饰
测试代码
写一个类来继承上面的抽象类,以此来测试在继承中 final 有否对多态中的影响
然后在基准测试中:
测试结果
非 final 结果