1.15 为什么Java中的文件名与公共类名相同?| Java Debug 笔记

本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看 活动链接

Debug 笔记
<为什么Java中的文件名与公共类名相同?>

提问

我很惊讶地看到下面的Java代码片段已编译并运行:

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

其中listOfNumbers是整数数组。

我以为最终声明只分配了一次。

编译器是否正在创建Integer对象并更改其引用?

回答一:

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

for (Iterator<Integer> iter = listOfNumbers.iterator(); iter.hasNext(); )
{
    final int i = iter.next();
    {
        System.out.println(i);
    }
}
复制代码

回答二:

有关涉及的范围规则的说明,请参见@TravisG。之所以使用像这样的最终循环变量的唯一原因是,如果您需要在匿名内部类中对其进行关闭。

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的范围,仅在实例化时才属于。如果没有final关键字,则当Runnable最终运行时,循环变量将对Runnable不可见。即使是这样,所有Runnable的值都相同。

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

再回答@mafutrct:
编写代码时,需要两个受众。第一个是计算机,只要它在语法上是正确的,它将对您做出的任何选择感到满意。第二个是为将来的读者(通常是您自己)准备的,这里的目标是传达代码的“意图”,而不会模糊代码的“功能”。语言特征应惯用,尽量少用解释,以减少歧义。

在使用循环变量的情况下,可以使用final来传达以下两种情况之一:单分配;或者,关闭。对循环进行一次简单的扫描将告诉您是否重新分配了循环变量。但是,由于创建闭包时两个执行路径的交织,很容易错过闭包意图捕获变量的情况。当然,除非您仅使用final表示要捕获的意图,否则对于读者来说,这是正在发生的事情。

文章翻译自Stack Overflow :stackoverflow.com/questions/3…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享