我有一个检查用户输入的值是否在数组范围内的方法:
public static void placeMove(int num1, int num2){
//checking if x and y are greater than rows and columns of a 2D array
if(num1 > rows-1 || num2 > columns-1){
System.out.println("This space is off the board, try again.");
int[] values = new int[2];
values = inputMove(); //calls inputMove method to ask user for new input
placeMove(values[0],values[1]); //calling itself to check
//if new values are prohibited
}
//code to place a value in grid[num1][num2]
}
我有一个 2D 数组(行和列的大小因设置而异):
char[][] grid = new char[rows][columns];
当我错误检查 num1/num2 是否大于它们各自的行/列时,我的 placeMove 方法给了我一个 ArrayIndexOutOfBoundsException。 placeMove 再次调用 placeMove,并且第一次调用 placeMove 的状态保存在堆栈中,一旦第二次调用 placeMove 的执行完成,那么第一次迭代就会使用堆栈中保存的局部变量的值恢复其进一步执行并导致异常。我该如何防止这种情况?感谢您的任何帮助!
非常简单:在递归调用后只需从函数return
- 或者将其他代码放入 else 块中:
placeMove(values[0],values[1]);
return; // <--
}
//code to place a value in grid[num1][num2]
或:
placeMove(values[0],values[1]);
}
else
{
//code to place a value in grid[num1][num2]
}
实际上,不需要递归调用,你可以有一个循环:
while(num1 >= rows || num2 >= columns)
// ^ instead of if ^ (additionally changed comparison)
{
System.out.println("This space is off the board, try again.");
int[] values = inputMove();
// ^ can assign directly,
// (the array you created previously is just GC'ed)
num1 = values[0];
num2 = values[1];
}
//code to place a value in grid[num1][num2]
编辑以回应您的评论:
我在我的主方法中分别调用了inputMove(),然后调用了placeMove(int num1,int num2),最后调用了一个checkWin(int num1,int num2)方法。checkWin() 方法使用从 inputMove() 方法返回的值。
那么你不应该在placeMove
内调用inputMove
,而是:
int main(String[] args)
{
int[] values = inputMove();
while(values[0] >= rows || values[1] >= columns)
// by the way: you do not check for NEGATIVE input!!!
{
System.out.println("This space is off the board, try again.");
values = inputMove();
}
placeMove(values[0], values[1]); // <- won't read input any more!
checkWin(values[0], values[1]);
}
实际上,这应该是一个新问题,下次最好这样做,最好参考当前的问题......
Edit2:实际上,正常检查输入是获取输入的一部分,所以我的建议是将while循环移动到inputMove
:
int[] inputMove()
{
int[] values = new int[2];
for(;;)
{
// read only ROW as before
if(0 <= values[0] && values[0] < rows)
break;
System.out.println("row out of range");
}
// now the same for COLUMN
return values;
}
Main 现在只需删除 while 循环:
int main(String[] args)
{
int[] values = inputMove();
placeMove(values[0], values[1]); // <- won't read input any more!
checkWin(values[0], values[1]);
}
这样,您就清楚地将与一个和另一个最密切相关的内容组合在一起。此外,使用行和列的两个单独循环,如果仅 comlumn 无效,则不会强制用户重新输入行......