【问题标题】:final variable interpretation最终变量解释
【发布时间】:2013-08-02 08:35:48
【问题描述】:

我知道编译器如何解释Java中的final关键字,但是我们程序员应该如何解释它的含义呢?应该是:

1) 这个变量不能改变(例如内部类使用)

2) 我不打算更改此变量(可能对成员变量有一些优化好处)。

我问这个问题是因为我处理过默认情况下所有内容都声明为 final 的代码(上面的选项 2),在我看来,这会降低关键字的价值并隐藏 真正 可以的值'不要改变!将变量声明为 final 是否还有性能优势?

【问题讨论】:

    标签: java performance final


    【解决方案1】:

    将每个变量声明为final 不会贬低final 关键字。它帮助开发人员调试应用程序以排除修改变量的可能性,尤其是在应用程序的多线程环境中。

    随着 java 8 的发布,我们又多了一个概念,叫做“effectively final variable

    从 lambda 表达式引用的局部变量必须是 final 或有效 final

    如果在本地块中初始化后未修改变量,则该变量被视为有效最终。这意味着您现在可以在匿名类或 lambda 表达式中使用不带 final 关键字的局部变量,前提是它们必须是有效的 final。

    如果您不想将有效的 final 声明为 final 变量,那么在您使用 lambda 表达式/匿名类时,此新功能会为您提供帮助。您可以避免为 effective final 变量声明 final 关键字。看看这个article

    【讨论】:

      【解决方案2】:

      我不久前写了a post about this

      Final 帮助阅读代码:

      • 不使用 final 一切都可能是可变的(潜在的混乱)
      • 它强制在变量可以使用之前对其进行设置(在构造函数中很有用)

      通过使用 final,你可以告诉编译器你的代码,它会帮助你作为回报。

      【讨论】:

        【解决方案3】:

        默认情况下所有的最终结果都是的。您越能将代码建模为不变性,就越容易推理。

        在我看来,使用final 几乎与性能无关。它是关于对代码的其余部分进行断言(没有改变这个变量),这可以帮助读者理解代码,并且可以被编译器检查。

        编辑:以上是我对字段的看法。对于局部变量(包括参数),我个人只在变量将用于匿名内部类时使用final。这与字段不同,因为:

        • 很容易看到方法的整个上下文 - 如果不是,这本身就是一个问题。
        • 由于它不代表对象(或类)的状态,所以不变性的好处并不真正适用。

        【讨论】:

        • 成员变量我接受这个,局部变量和参数呢?除非确实需要,否则将它们标记为 final 肯定没有什么好处?
        • 我对@9​​87654323@ 的唯一抱怨是我需要写它。例如,它会削弱方法签名,所以我不会在那里使用它。相反,我有一个更改参数的编译器警告。
        • @StuPointerException:对于局部变量和参数我个人同意——我只将它用于需要在内部类中使用的变量。将进行编辑以表明这一点。
        • @MarkoTopolnik 当然,Java 应该有相反的东西:像 'var' 或 'mutable' 这样的关键字。
        • 我认为“final”的冗长不鼓励使用它。例如,在 Scala 中,final 变量很多更常见,因为只需编写 val 而不是 var。我最近在想,为final 变量添加一个新的赋值运算符会很酷,例如:=(当然可以省略 final 关键字)。
        【解决方案4】:

        我不能对 Jon 已经说过的内容添加太多内容,但为了完整起见,JLS 17.5.3 说 final 字段也可能导致优化;

        如果在字段声明中将 final 字段初始化为编译时常量表达式(第 15.28 节),则可能不会观察到对 final 字段的更改,因为 该 final 字段的使用在编译时被替换为常量表达式的值

        【讨论】:

          【解决方案5】:

          final关键字应该被抛弃,它应该在所有适用的情况下都是标准的,并且finality应该只能用一个关键字来撤销

          this_variable_will_change_unexpectedly_behind_your_back
          

          此关键字不应被任何 IDE 自动完成,也不应使用 Ctrl-V 插入。

          【讨论】:

          • 完全基于意见,但我碰巧分享了它的每一个字:)
          • 我喜欢它,除了 ctrl-V 部分;)
          • 还有一个笑话,“变量”的意思是“它可以在你背后改变”......如果他的变量在一个表达式中改变,数学家会怎么说?
          【解决方案6】:

          确实使用了final变量,因此没有人可以更改值,它在java中作为常量。

          我举个例子

          我已经创建了一个也可以被其他人使用的包,现在需要设置一些配置变量才能正确运行它。可以说它的登录包。所以可能会有一些加密选项,比如

          encryption_method = HASH_ENCRYPTION

          加密方法 = SYMMETRIC_ENCRYPTION

          我们可以定义最终变量,而不是传递整数 1、2、3,它可以帮助开发人员以更易读的形式和ofcource 我不希望用户更改它,所以我保持它是最终的,否则内部逻辑可能会中断

          【讨论】:

            【解决方案7】:

            final 变量通常是a good thing。注意,这只表示变量不能被重新赋值,但是它指向的对象可以改变,如果它是可变的。

            性能方面,final 允许更激进的compiler optimisations

            规范允许对最终字段进行积极优化。在线程中,允许使用未在构造函数中发生的对最终字段的修改来重新排序对最终字段的读取。

            【讨论】:

              【解决方案8】:

              我不明白你为什么认为没有价值。

              当我看到所有最终变量时,这意味着该类是不可变的。这是一件好事,因为不可变类本质上是线程安全的。

              【讨论】:

              • 最终列表不是一成不变的。
              • 参考当然是。您应该使用同步集合来修改其内容。
              【解决方案9】:

              第二个选项是保障措施。它会阻止您意外更改或重新分配。因此,提供它很有用,您可以在决定要更改该变量时将其删除。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-04-14
                • 2015-03-13
                • 2018-09-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-02-25
                • 2014-12-07
                相关资源
                最近更新 更多