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

为什么在Java中必须初始化嵌套的循环控制变量?,java,initialization,nested-loops,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}

我编写了一个简单的“在多维数组中查找数字”,它包含在官方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!!!");
    }
类标记为break{
公共静态void main(字符串[]args){
int[][]数字={
{22, 34, 675, 23, 23},
{34, 76, 98, 23, 11},
{65, 234, 87, 23, 76}
};
int searchFor=123;
布尔值=false;
int i;

int j=0;//如果
numbers.length
为0,则内部循环将永远不会运行,因此
j
将永远不会被初始化,也就是说,您永远不会到达语句
j=0;

请考虑以下代码:

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);
int j=1234567;
int end=-100;
for(int i=0;i

尝试不同的
end
值。请注意,当输出为
1234567
时,我无法将其放入注释中,因此我将代码放在此处

IMHO最好使用不会遇到这些问题的结构

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!!!");
}
找到:{
for(int i=0;i

变量的范围仅限于可以安全使用的地方。

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

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

Java语言规范第16节定义了变量“使用前明确分配”的原因,基本上是通过查看代码流(语法结构),但忽略其他变量的内容(即使已知),并忽略沿途调用的确切方法

但我总是初始化
j

是的。但为了证明这一点,您需要深入研究
数字
的初始内容,了解
长度
方法的工作原理,甚至排除其他线程获取对
数字
的引用并在主线程执行时修改数组的可能性

但是当设置了
found
时,我不会访问代码路径之外的
j
,因此,
`j
被初始化。

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

为什么
i
有什么不同?

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

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

就JLS第16节而言,这不会改变任何事情。您的编译器不允许您保存这种形式化的初始值设定项,因为该程序可能无法移植到其他可能不是同样智能的Java编译器