什么是“异常控制”循环?

4
我正在尝试回答学习指南上的一个问题,该问题要求:
编写一个异常控制循环,循环直到用户输入介于1和5之间的整数。
我无法理解这个问题的真正含义,因为我以前从未听说过这个术语,但这是我最好的猜测:
    Scanner input = new Scanner(System.in);
    int a = 0;

    while(a <= 0 || a > 5)
    {
        try {
            a = input.nextInt();

            if(a <= 0 || a > 5)
                throw new OutOfRangeException(); //my own Excpt. class
        } catch (OutOfRangeException e) {
            System.out.println(e.getMessage());
        }
    }

你们觉得呢?我是否有所遗漏?


1
这个问题本身对我来说就像是有一个巨大的标志:“不要做!” - Bobby
导游的意思是不是类似这样:while(true) {if(input在1到5之间) {throw Exception();}} - Bobby
作为一个有趣的注释,你不是第一个对此感到困惑的人 - Bobby
3
你的老师应该被解雇,因为有更好的方法来教授循环行为的复杂性。话虽如此,@ArmenTsirunyan的回答应该能指引你朝着正确的方向前进。 - Perception
我对如何满足规格的第一个想法是使用 while(true) 循环,该循环将无限循环并继续要求用户输入,如果输入超出范围。 如果给定的输入在范围内,则抛出 InputIsCorrectException 异常。 在循环外部,捕获并忽略异常。 - Alderath
个人而言,我认为 while(true) 循环是代码异味。它完全否定了循环条件控制循环的想法,而是滥用异常和/或 break 来替代它。 - Ingo Bürk
6个回答

7
我认为你的捕获语句应该放在循环外面。
 Scanner input = new Scanner(System.in);
 int a = 0;
 try
 {
    while(true)
    {       
        a = input.nextInt();
        if(a <= 0 || a > 5)
            throw new OutOfRangeException(); //my own Excpt. class
    } 
 }
 catch (OutOfRangeException e) {
    System.out.println(e.getMessage());
 }

我实际上没有听说过“异常控制循环”这个术语,但我认为它意味着一个无限循环,直到出现异常才退出。似乎很合理。

正如评论所说,如果您需要循环直到用户输入1到5之间的数字,那么应该抛出的条件是

 if(a >= 1 && a <= 5)

@Bobby:我也是这么想的,但后来我觉得可能是我对“until”这个词的理解有误。 - Armen Tsirunyan
作业要求是“循环直到用户输入介于1和5之间的整数”。 - Bart van Heukelom
嗯,抛出异常会导致捕获被触发并且 while 循环被中断吗?如果是这样的话,那么就满足了所说的条件。 - Travis J
此外,您的条件范围被反转了,应该是 if(a > 0 && a < 5)。 - Travis J
谢谢Armen,我会采用你的解决方案并希望一切顺利! - LTH

2
"Exception-controlled" 不是一个标准术语,而且使用异常来控制流程是众所周知的不良实践。但为了最清楚地演示它(即糟糕的情况),我将省略循环检查,并只写 while(true),以便明显地表明循环仅由异常控制。

2
一个非常丑陋的异常控制循环示例:
String[] array = new String[] {"a", "b", "c"};

try {
    for (int i = 0;;i++) {
        System.out.println(array[i]);
    } 
} catch (ArrayIndexOutOfBoundsException e) {

}

与其检查条件并在条件不再成立时结束执行,如下所示:

i < array.length

我们执行循环,直到抛出异常。这样做显然很不好。它会让代码变得混乱,如果你在循环内调用一个可能也会抛出ArrayIndexOutOfBoundsException的方法,那么该异常会被吞掉。

1
唉...希望我永远不会看到这样的东西。 - Aaron

1
感谢我的好朋友大数先生,我能够挖掘出这个东西的一个例子。虽然我以前从未听说过这个术语,但一旦看到一个例子,它就突然变得有意义了。
Scanner scanner = new Scanner(System.in);
int number = 0;
boolean done = false;

while(!done) {
    try {
        number = scanner.nextInt();
        done = true;
    } catch( InPutMisMatchException ex) {
        // tell the user that that's not a number!
    }
}   

我不能保证这确实是指南的意思!


1
“异常控制循环”可能意味着在捕获异常时循环,直到达到适当的输入后退出。虽然这个术语似乎是由那个“学习指南”想出来的。
Bobby的答案几乎完美,只是缺少了在catch块中防止进入无限循环的2个重要事项。
import java.util.InputMismatchException;
import java.util.Scanner;

public class LoopWhileException {

    public static void main(String[] args) {
        boolean isNumber = false;
        int number = 0;

        Scanner scan = new Scanner(System.in);

        while(!isNumber) {
            try {
                System.out.print("Enter an integer: ");
                number = scan.nextInt();

                System.out.print("Your integer is: " + number);

                scan.close(); // close resources for good practice

                // not true = false, exits loop on integer input
                isNumber = true; // break; can also be used

            } catch(InputMismatchException ime) {
                System.out.print("Input is not a number!\n\n");

                scan.nextLine(); // clears input buffer

                // not false = true, re-enters while loop on catch
                isNumber = false; 
            }
        }   
    }
}

如前所述,像这样循环异常通常不被视为良好的实践,但这仅是所谓“异常控制”场景的参考。


0

也许它指的是这本书中的技术,该技术几乎与此技术相同:Jack Shirazi-Java Performance Tuning(第二版)-O'Reilly Media(2003),第7.3章异常终止循环

链接:http://etutorials.org/Programming/Java+performance+tuning/Chapter+7.+Loops+Switches+and+Recursion/7.3+Exception-Terminated+Loops

异常用于优化while循环:当while条件不满足时,异常退出循环而无需重新测试条件。但在这种情况下,它可能不是优化,因为它使用if进行条件测试而不是while。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接