局部变量在类的方法中成为最终变量——但为啥呢?

Posted

技术标签:

【中文标题】局部变量在类的方法中成为最终变量——但为啥呢?【英文标题】:local variable made final in method of a class -- but why?局部变量在类的方法中成为最终变量——但为什么呢? 【发布时间】:2013-07-29 16:16:18 【问题描述】:

今天在google上搜索某段代码时,偶然发现了一个问答博客,上面说我们可以在类的方法中声明一个局部变量为final。然而,作者不太愿意解释这样做的必要性/好处。

喜欢

public class A

 private void show()
 
  final String s="checking";
 

我会寻求 java 大师的帮助来教育我。提前感谢您的支持和指导。

最好的问候!

【问题讨论】:

Using "final" modifier whenever applicable in java 的可能重复项 【参考方案1】:

当一个 var 是 final 时,你不能改变它。这意味着 - 一个你不能犯的错误 - 或者,更准确地说,一个逻辑错误会导致编译错误,并节省长时间的调试。


不要与您无法继承的final class 混淆。


more data could be found in wikipedia

【讨论】:

谢谢先生!是的,我理解那部分,但是由于该变量不是该类的成员变量,而是仅具有该方法的本地范围,继承可能对其产生什么影响?最终需要什么?如果我的问题对你有意义,请告诉我。 final 不仅仅是为了继承。当您声明 var final 时,这意味着您无法更改它。就像 c/c++ 中的 const【参考方案2】:

变量可以放在只读存储器中,使其操作起来更快。

这样做也很合乎逻辑,例如用于表示局部常量或确保某个值不会被意外更改。这使它成为将错误转化为编译器错误的有用方法。

此外,它允许在内部/匿名类中使用变量,正如其他答案所指出的那样。

【讨论】:

【参考方案3】:

final 添加到所有不应更改的内容只会缩小您(或下一个正在处理您的代码的程序员)误解或误用导致您代码。

取自this answer 到一个类似的问题。

【讨论】:

【参考方案4】:

除了强制变量在初始化后保持不变外,将变量声明为final 可以让方法本地内部类访问它。 更详细的信息可以通过查看下面一小段代码的反汇编代码来获得:

class MyFinal 

    public static void main(String[] args) 
    
        String str = "java";
        final String str1 = "Hello";
    

上述程序的反汇编代码如下:

J:\>javap -c MyFinal
Compiled from "MyFinal.java"
class MyFinal extends java.lang.Object
MyFinal();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #2; //String java
   2:   astore_1
   3:   return


在上面反汇编代码的main方法中我们看到,java编译器保留了non-final变量str的String对象创建代码,但默默地省略了final String str1 = "Hello";的String对象创建代码。之所以如此,是因为 str1 没有在任何地方的方法中使用。因此,它有助于编译器优化代码,从而避免在没有使用的情况下创建不必要的对象。

【讨论】:

【参考方案5】:

除了其他答案,创建变量final 可以在类和接口的内联实现中使用该变量:

final String test = "test";

foo = new Foo() 
        public void bar() 
            System.out.println(test);
        
    ;

编辑: 如果您是初学者,还值得指出的是,变量实际上是对实例引用。当你创建一个变量final 时,你实际上是在创建引用常量,也就是说,最终变量在初始化后永远不能引用其他实例。这没有声明实际的引用实例是否是常量。

例如,如果你说final String[] foo = "bar", baz" ,你可以foo[0] = "sheep",即使foofinal。你不能做的是将foo 变量引用到其他东西,比如foo = new String[]...foo = someOtherArray。这与 mutabilityimmutability 有关,这些概念有点类似于 final,因此可能值得研究一下。

【讨论】:

很好的答案先生!非常感谢:)【参考方案6】:

能够轻松判断变量不会改变是有道理的。如果这是一个原语,您可以认为该值是不可变的,如果不是,您现在知道该值将始终是同一个实例(可以更改哪个状态)。

这对于程序的可读性很有用,因此我们可以确定变量永远不会被重新分配。它对匿名函数也很有用,在这里解释:Why do we use final keyword with anonymous inner classes?

【讨论】:

以上是关于局部变量在类的方法中成为最终变量——但为啥呢?的主要内容,如果未能解决你的问题,请参考以下文章

全局变量和局部变量的区别

在方法中定义的内部类称为局部内部类

成员变量与局部变量

成员变量和局部变量

在类范围内声明一个与类属性同名的局部变量

JAVA基础——类和对象