【问题标题】:What does "final" do if you place it before a variable?如果将“final”放在变量之前,它会做什么?
【发布时间】:2010-10-25 02:29:21
【问题描述】:

非常基本的问题,但是,如果将“final”放在下面的变量之前会做什么......

final EditText myTextField = (EditText) findViewById(R.id.myTextField);

final 是做什么的?

【问题讨论】:

  • 好吧!我想我得到了答案! (6 个答案!哇!)所有这些工作。

标签: java


【解决方案1】:

简答

停止将“myTextField”变量分配给其他对象。

长答案

  • 不会阻止“myTextField”变量发生突变,例如将其字段设置为新值。
  • 使代码更具可读性(恕我直言),因为读者永远不必怀疑“myTextField”变量是否会在稍后在代码中重新分配。
  • 防止意外重新分配变量的错误类别(与使实例不可变的原因相同,只是在较小的范围内)。

由于上述原因,我总是尽可能将“final”修饰符应用于静态字段、实例字段、局部变量和方法参数。它确实使代码有点膨胀,但对我来说,额外的可读性和健壮性是值得的。

【讨论】:

  • 如果它提供有用的功能,我不会认为它臃肿。
  • 我以为我对 final 的了解已经足够了,但现在我意识到我必须了解更多。 :)
【解决方案2】:

关键字final,在此上下文中,意味着您不能更新隐式指针myTextField 以指向不同的对象(尽管您可以修改myTextField 指向的对象)。该关键字还可用于防止覆盖(当应用于类或方法时)。

您可能会看到这种情况的一个原因是引用局部变量的匿名类只能引用标记为final 的变量。这样匿名类只需要存储一个重复的引用,而不需要维护对本地函数堆栈的完全访问。例如:

Runnable r = new Runnable() { public static void run() {
         // do something with myTextField
         // this would require myTextField to have been marked final.
}};
doSomethingLater(r);

【讨论】:

    【解决方案3】:

    其他答案都没有注意到的一件事是 final 属性相对于 Java 内存模型具有特殊属性。最终效果是一个线程可以安全地访问final 属性的值,而无需采取步骤与其他线程同步。

    跟进

    这是 JVM 特有的吗?

    Java 内存模型的规范是 Java 语言规范的一部分,并且 (AFAIK) 自 Java 1.5 以来没有改变。从这个意义上说,这不是 JVM 特定的。

    但是,如果您不遵守规则(即,如果您的代码未正确同步其对共享数据的使用),Java 的行为取决于各种因素,包括您运行应用程序的硬件。

    除其他外,Java 内存模型旨在允许多核机器运行许多 Java 线程,而不必不断刷新内存缓存......这会降低性能。基本上,它指定了一些规则来保证一个 Java 线程可以看到来自另一个线程的内存更新。如果应用程序不遵守规则,可能线程将看到由其他线程写入的某些字段的陈旧(过期)值,从而导致偶尔出现未定义的行为。 p>

    【讨论】:

    • 否:它在 JMM 中。 stackoverflow.com/questions/3974350/…
    • @andersoj - 我刚刚说过:-)
    • 死记硬背被低估了。 ;-)
    • @Stephen:显然我的拼写练习包括不充分的死记硬背。
    • @andersoj - 或者换句话说,你的气味很臭:-)
    【解决方案4】:

    final 关键字将确保 myTextField 持有任何 findViewByID() 返回的引用,并禁止对 myTextField 变量的任何其他赋值,即在执行之后

    final EditText myTextField = (EditText) findViewById(R.id.myTextField);
    

    如果您尝试为 myTextField 分配任何值,您将收到编译器错误。

    【讨论】:

      【解决方案5】:

      myTextField 的引用一旦分配就无法修改。更多信息来自Wikipedia

      最终变量只能赋值 一次。此任务不授予 变量不可变状态。如果 变量是类的一个字段,它 必须在构造函数中赋值 它的类。 (注:如果变量是 参考,这意味着 变量不能重新绑定到 引用另一个对象。但是 它引用的对象仍然是 可变的,如果它最初是 可变的。)与 a 的值不同 常量,final的值 变量不一定是已知的 编译时间。

      【讨论】:

        【解决方案6】:

        如果一个变量被标记为final,那么该变量的值就不能改变,即当与变量一起使用时,final 关键字使其成为一个常量。如果您在程序执行过程中尝试更改该变量的值,编译器会给您一个错误。

        【讨论】:

          【解决方案7】:

          关键字finalmyTextField 声明为常量变量。

          【讨论】:

            【解决方案8】:

            试图用代码流解释final修饰符的使用:

            public static void main(String[] args) {
            
                class Person {
                    String name;
                }
            
                Person peep1 = new Person(); // points to obj at address HEX001
                peep1.name = "Mike"; 
                System.out.println(peep1.name);
            
                Person peep2 = new Person(); // points to obj at address HEX002
                peep2.name = "Jenna";
                System.out.println(peep2.name);
            
                final Person peep3 = peep1; // also points to obj at address HEX001
                System.out.println(peep3.name);
            
                peep1.name = "pwnd"; // modifies obj at address HEX001
                System.out.println(peep1.name);
                System.out.println(peep3.name);
            
                peep1 = peep2; // now it points to obj at address HEX002
                System.out.println(peep1.name);
            
                System.out.println(peep3.name); // still points to obj at address HEX001
            
                peep2.name = "Henna"; // modifies obj at address HEX002
                System.out.println(peep2.name);
            
                peep3 = peep2; // compiler error "The final local variable peep3 cannot be assigned. It must be
                                // blank and not using a compound assignment"
            
                System.out.println(peep3.name); // assuming it now points to obj at address HEX002
            
            }
            

            输出:

            Mike
            Jenna
            Mike
            pwnd
            pwnd
            Jenna
            pwnd
            Henna
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-09-27
              • 2015-04-19
              • 2016-05-30
              • 2017-05-14
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-09-03
              相关资源
              最近更新 更多