为什么在Java中必须初始化嵌套循环控制变量?

时间:2012-09-07 14:49:30

标签: java initialization nested-loops

我在官方java教程中写了一个简单的“在多维数组中查找数字”。这是教程中包含的代码:

class LabeledBreak {
    public static void main(String[] args) {
        int [][] numbers = {
            {22, 34, 675, 23, 23},
            {34, 76, 98, 23, 11},
            {65, 234, 87, 23, 76}
        };

        int searchFor = 123;
        boolean found = false;
        int i;
        int j = 0;  // <-- this line

search:
        for (i = 0; i < numbers.length; i++) {
               for (j = 0; j < numbers[i].length; j++) {
                if (searchFor == numbers[i][j]) {
                    found = true;
                    break search;
                }
               }
        }

        if (found == true)
            System.out.println("Found " + searchFor + " at index " + i + ", " + j);
        else
            System.out.println(searchFor + " not found!!!");
    }

我无法理解这里初始化“j”的重点是什么。我尝试删除初始化语句,并使其只是一个声明。但我得到了这个错误:

“变量j可能尚未初始化”

为什么我要初始化“j”?为什么“i”也不需要初始化?

4 个答案:

答案 0 :(得分:11)

好吧,如果numbers.length为0,则内循环永远不会运行,因此永远不会初始化j,即你永远不会到达j = 0;语句。

答案 1 :(得分:2)

我无法将其纳入评论,因此我已将代码放在此处。

恕我直言,最好使用不会遇到这些问题的结构。

FOUND: {
    for (int i = 0; i < numbers.length; i++)
       for (int j = 0; j < numbers[i].length; j++)
            if (searchFor == numbers[i][j]) {
                System.out.println("Found "+searchFor+" at index "+i+", "+j);
                break FOUND;
            }
    System.out.println(searchFor + " not found!!!");
}

变量的范围仅限于安全使用的范围。

答案 2 :(得分:1)

考虑以下代码:

int j = 1234567;
int end = -100;
for (int i = 0; i < end; i++)
    for (j = 0; j < 10; j++)
        System.println("Hello.");
System.println("j is "+j);

尝试end的不同值。请注意输出为1234567

答案 3 :(得分:0)

为什么Java会关注禁止读取未初始化的变量?

此类代码构造往往是非确定性的,因此难以调试,因此不可靠。此外,不加选择的堆栈内存重用可能导致安全漏洞。

Java语言规范,第16节,定义了什么使变量“在使用前明确分配”,主要是通过查看代码流(语法结构),但忽略其他变量的内容,即使已知,并忽略了确切的方法是什么一路上叫。

但我总是初始化j

是的,你这样做。但要证明这一点,您需要深入了解numbers的初始内容,了解length方法的工作原理,甚至排除其他线程获取对{{1}的引用的可能性。并在主线程执行时修改数组。

但在设置numbers时,我不会在代码路径之外访问j,因此found已初始化。

正如你所说。但是JLS第16节只考虑代码结构,而不考虑其他变量的值,例如`j

为什么found有所不同?

i的初始化纯粹在语法上保证是在外部循环中发生的第一件事,即使它的主体(纯粹是假设的)根本不执行。

如果我的Java编译器足够聪明,看不到我没有访问任何未初始化的变量怎么办?

就JLS第16节而言,这并没有改变任何东西。您的编译器不允许您保存这样的形式化初始化器,因为该程序可能无法移植到可能不同样智能的其他Java编译器。