3

我写了一个简单的“在多维数组中查找数字”,包含在官方 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

4 回答 4

11

好吧,如果numbers.length为 0,则内部循环将永远不会运行,因此j永远不会被初始化,即您永远不会到达 statement j = 0;

于 2012-09-07T14:52:25.127 回答
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!!!");
}

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

于 2012-09-07T14:59:47.983 回答
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.

于 2012-09-07T14:54:47.030 回答
0

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

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

Java 语言规范第 16 节定义了使变量“在使用前明确赋值”的原因,主要是通过查看代码流(句法结构),但忽略其他变量的内容,即使已知,也忽略沿方法。

但我总是初始化j.

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

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

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

为什么有i什么不同?

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

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

就 JLS 第 16 节而言,这不会改变任何事情。您的编译器不允许您保存此类形式初始化程序,因为该程序可能无法移植到其他可能不那么聪明的 Java 编译器。

于 2012-09-09T19:32:47.797 回答