前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >请不要再说 Java 中 final 方法比非 final 性能更好了

请不要再说 Java 中 final 方法比非 final 性能更好了

作者头像
哲洛不闹
发布2018-09-14 11:21:35
1.3K0
发布2018-09-14 11:21:35
举报
文章被收录于专栏:java一日一条

无继承

有 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 结果

有 final 结果

总对比

它们字节码的区别

可以看到,除了它们的方法签名和方法名字不同之外其他的都是一样的,包括JVM调用指令也完全是一样的。

总结

可以看到它们几乎是一样的。

总结

基于上面的基准测试结论,我认为滥用或刻意为了所谓的提升性能,而去为每一个方法尽可能添加 final 的关键字是不可取的。使用 final ,更多的应该是根据Java对 final 的语义来定义,而不是只想着为了提升性能(而且这影响可以忽略不计)而刻意用 final.

使用 final 的情况:

final 变量: 表示只读(只初始化一次,但可多次读取) final 方法:表示子类不可以重写。(网上认为 final 比非 final 快,就是认为它是在编译的时候已经静态绑定了,不需要在运行时再动态绑定。这个可能以前的JVM上是正确的,但在现代的JVM上,这个可以认为没什么影响,至少我在基准测试里是这样子) final 类: 它们不能被继承,而且final类的方法,默认也是 final 的。

关于这个 final 的性能问题,我也Google了下,发现 stackoverflow 上,也有类似的问题:stackoverflow(https://stackoverflow.com/questions/4279420/does-use-of-final-keyword-in-java-improve-the-performance)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java一日一条 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 无继承
    • 有 static 修饰
      • static final
      • static 非 final
      • 结果
      • 分析
      • 字节码级别的差别
      • 在调用者上面的字节码差别
    • 无 static 修饰
      • 结果
      • 分析
      • 字节码级别的差别
      • 在调用者上面的字节码差别
      • 总结
  • 有继承
    • 无 final 修饰
      • 有 final 修饰
        • 测试代码
          • 测试结果
            • 它们字节码的区别
              • 总结
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档