首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >"final int“在Java for循环中是如何工作的?

"final int“在Java for循环中是如何工作的?
EN

Stack Overflow用户
提问于 2010-10-12 09:50:55
回答 2查看 15.6K关注 0票数 60

我很惊讶地看到以下Java代码片段被编译并运行:

代码语言:javascript
复制
for(final int i : listOfNumbers) {
     System.out.println(i);
}

其中listOfNumbers是整数数组。

我以为最终的声明只被赋值一次。编译器是否创建了一个Integer对象并更改了它引用的内容?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-12 09:55:07

想象一下速记看起来很像这样:

代码语言:javascript
复制
for (Iterator<Integer> iter = listOfNumbers.iterator(); iter.hasNext(); )
{
    final int i = iter.next();
    {
        System.out.println(i);
    }
}
票数 66
EN

Stack Overflow用户

发布于 2010-10-12 10:40:22

有关涉及的作用域规则的解释,请参阅@TravisG。使用像这样的final循环变量的唯一原因是,如果需要在匿名内部类中关闭它。

代码语言:javascript
复制
import java.util.Arrays;
import java.util.List;

public class FinalLoop {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(new Integer[] { 0,1,2,3,4 });
        Runnable[] runs = new Runnable[list.size()];

        for (final int i : list) {
            runs[i] = new Runnable() {
                    public void run() {
                        System.out.printf("Printing number %d\n", i);
                    }
                };
        }

        for (Runnable run : runs) {
            run.run();
        }
    }
}

循环变量在执行时不在Runnable的作用域中,只有在实例化时才在Runnable的作用域中。如果没有final关键字,循环变量在最终运行时对Runnable是不可见的。即使是这样,对于所有的Runnables,它也是相同的值。

顺便说一句,大约10年前,您可能会看到在局部变量上使用final的速度有很小的提高(在一些很少的情况下);很长一段时间都没有出现这种情况。现在,使用final的唯一原因是允许您使用这样的词法闭包。

回复@mafutrct:

当你写代码的时候,你是为两个读者写的。第一个是计算机,只要它在语法上是正确的,它就会对你所做的任何选择感到满意。第二个是给未来的读者(通常是你自己),这里的目标是传达代码的“意图”,而不会模糊代码的“功能”。语言功能应该以习惯用法使用,并尽可能少地解释,以减少歧义。

在循环变量的情况下,使用final可以用来传递两件事中的任何一件:单赋值;或者闭包。简单的循环扫描就会告诉您循环变量是否被重新赋值;然而,由于创建闭包时两个执行路径的交错,很容易遗漏闭包旨在捕获变量的信息。当然,除非您只使用final来表示捕获意图,这时读者就会明白正在发生的事情。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3911167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档