在java中使用最终局部变量

Ani*_*kur 32 java final local-variables

我想知道是否有使用最终局部变量的可用性.当继承进入图像时,无论如何都不会覆盖变量.例如,如下的简单代码

public static void main(String args[]) {
    final String data = "Hello World!";
    System.out.println(data);
}
Run Code Online (Sandbox Code Playgroud)

这个例子非常简单,可能不是相关的代码,但问题更通用.我看过很多代码(都包含在main函数中,它们都有最终的局部变量)是否有任何可用性来声明局部变量作为最终的其他而不是他们不能在同一个功能本身编辑?

Jon*_*eet 59

首先,关于变量"被覆盖"的部分final有两个截然不同的含义.对于类和方法,它是关于继承; 对于变量,它是关于只读的.

最终局部变量有一个重要的"特征":它们可以在本地(通常是匿名的)内部类中使用.非最终的局部变量不能.final根据我的经验,这是局部变量的主要用途.

public void foo() {
    final String x = "hello";
    String y = "there";

    Runnable runnable = new Runnable() {
        @Override public void run() {
            System.out.println(x); // This is valid
            System.out.println(y); // This is not
        }
    };
    runnable.run();
}
Run Code Online (Sandbox Code Playgroud)

请注意,作为一种风格,有些人final甚至喜欢在他们没有在本地内部类中捕获变量时使用.final作为默认值,我肯定会感到很自在,但是对于"非最终版本",我会发现不同的修饰符,但我发现在任何地方明确地添加修饰符太过分散注意力.

  • @Ankur很长一段时间都没有这样的情况.如果变量是否被更改,编译器可以很容易地计算出来并相应地进行优化.这是[另一个SO答案](http://stackoverflow.com/a/4279442/2071828). (9认同)
  • @Ahmed:在幕后,编译器在匿名内部类中生成一个实例变量,并在创建实例时复制原始变量的值.这对你来说是否比对现有范围以外的原始变量的考虑更有用或更少是你的致电:) (4认同)
  • @Jon Skeet假设这些变量超出其本地范围是正确的,因为它们可以被匿名内部类访问吗? (2认同)

Joh*_*ith 9

可以从匿名内部子类访问最终局部变量,而非最终局部变量可以不访问.


Kru*_*hna 8

是的,可用性是: - 本地最终变量可由方法内部类访问.由于局部变量存在于堆栈中并且仅在方法的生命周期中存在,但是内部类对象可能寿命更长,因此内部类不能访问任何非最终局部变量.但是一旦变量是final,那么内部类确保该值不会改变,因此它保留了最终局部变量的私有副本以供使用.


Alg*_*giz 6

完美答案Jon Skeet但最终变量还有另一个(小)好处.

编译器将确保最终变量只设置一次.

假设你必须初始化一个变量,并且值的计算是复杂的(if-then-else中的if if-then-else多个).您可能编写的代码在某些条件下不会初始化变量(或将其初始化两次).当然,这是一个错误.使变量final将允许编译器检查最终变量是否只设置一次.如果你有错误,你会很快知道.

正如我所说,收益甚微但仍然得心应手.


Sub*_*der 5

是的,有一个小例子,我们通常可以使用它 -

片段:

final Boolean data = Boolean.TRUE;
button.addListener(SWT.Selection, new Listener() {
    public void handleEvent(Event event) {
        if (data ) {
                     ....
                }
        }
});
Run Code Online (Sandbox Code Playgroud)

它是匿名内部类的一个使用示例.如果你想在内部calss中使用你的局部变量,你必须做final.