用final修饰局部变量是否为良好的编码习惯?

最近阅读代码的时候,发现一些程序员很喜欢用final修饰局部变量,这到底是不是一个良好的习惯呢?
于是我查阅了相关资料,发现《并发编程实战》一书中的【3.4.1 Final域】提到

正如“除非需要更高的可见性,否则应将所有的域都声明为私有域”是一个良好的编程习惯,
“除非需要某个域是可变的,否则应将其声明为final域”也是一个良好的编程习惯。

查阅了相关的博文:
JAVA局部变量加final修饰的好处
JVM对于声明为final的局部变量做了哪些性能优化?

发现final的好处主要有:

  1. 被final修饰的基本数据类型不可变,引用数据类型地址不可被修改;
  2. 访问final变量的速度快;
  3. (待总结)

  • 这是否意味着日常在写代码时,要尽量给局部变量用final修饰?
  • 函数中大部分变量都是用final修饰的,是否会影响代码的阅读体验?
阅读 10.6k
3 个回答

访问final变量的速度快这个结论有什么依据吗?

我所了解的,JVM会对final变量的访问会禁止重排序优化,如果不使用final,访问变量时会进行重排序优化从而提高性能,但是在多线程情况下,重排序可能会造成线程安全问题,所以使用final修饰共享变量会避免这种重排序。专业的话讲就是防止变量从构造方法中逸出。另外final修饰的类变量虽然是共享的,但不可变能保证他的线程安全。

不过用final修饰方法和类确实能提高性能,如果没有final修饰,那么该类可能会被继承,JVM需要为继承做一些准备,如果有final修饰,相当于告诉JVM,该类或方法是不会被继承的,所以JVM会省掉哪些准备的时间。

对于局部变量,看看R大的回答:
https://www.zhihu.com/questio...

最重要部分是,用final修饰局部变量,编译器会进行常量折叠。

引用下之前在阿里开发手册上面对final的用法推荐吧:

clipboard.png
在我看来,

  1. 使用final可以使你的代码意图更加明确,将变量标记为final告诉读者该变量永远不会在分配时发生变化。这在阅读代码时非常重要
  2. 它可以作为编译器可能启用优化的提示。

第一个问题:
并不,局部变量设置为final通常为常量,即初始化的那一刻就不会再改变了。而我们写一个方法的时候所定义的变量基本是要经常改变的,比如for循环的那个i。
第二个问题:
不用。
出现final修饰符就是告诉我们这块不能动。甚至会增加代码的可读性。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏