为什么在Java中必须初始化嵌套的循环控制变量?
我编写了一个简单的“在多维数组中查找数字”,它包含在官方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}
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编译器