捕获异常并返回自定义消息

3

我正在完成一些学校作业,如果“if”语句中的条件得到满足,我需要抛出一个异常。

public class Fibonacci {
private static final long MAX = 91;

public static long finonacciGetal(int n) {
        if (n > MAX || n < 0) throw new FibonacciException();
        else {

            long eerste = 0;
            long tweede = 1;
            long getal = 0;

            for (int i = 0; i < n; i++) {
                getal = eerste + tweede;
                eerste = tweede;
                tweede = getal;
            }
            return getal;
    }
}

现在我创建了一个自定义的异常,在此异常中返回了一个错误消息,但它仍然会打印出堆栈跟踪。因此,有没有一种方法可以从异常类本身隐藏它?因为如果我使用try-catch块,它会在分配使用本地变量时不断出问题。程序应该在抛出1个异常后停止。

提前感谢!

编辑:按要求提供我的自定义异常:

public class FibonacciException extends ArithmeticException {
public FibonacciException() {
    super();
    System.out.println("Max value surpassed");
}

}


只有在以下情况下才会打印出异常信息:a)捕获并打印它或b)不捕获并且默认处理程序打印它。 - Peter Lawrey
使用递归算法。迭代对于斐波那契数列不是“纯粹”的。 无符号整数fib(无符号整数n){ 如果(n == 0)返回0; 如果(n == 1)返回1; 返回fib(n-1)+ fib(n-2); } - Wojciech Szymski
1
@WojciechSzymski 这个问题在于它的时间复杂度是O(fib(N)),这相当于指数级时间复杂度。 - Peter Lawrey
1
@WojciechSzymski (1) 这与问题无关; (2) 请看Peter的评论,如果您使用递归,将会为相同的N重新计算fib(N)多次; (3) 在程序中使用递归来完成可以轻松使用迭代完成的任务是没有任何价值的。没有。递归可能看起来很“纯粹”,但这只意味着数学家会喜欢它。程序员不太喜欢。不必要的递归是一种癌症。请不要推荐它。 - ajb
@Glenndisimo,我认为你的问题需要进一步澄清。你说这个方法应该抛出一个异常,但是如果有人需要捕获它,那么是谁呢?一个方法抛出异常然后自己捕获异常并不是正常的情况,所以我不理解你关于返回值和局部变量的评论。如果这个方法抛出了异常,那么这个方法将不会返回任何东西,并且它的局部变量也变得无关紧要。 - ajb
显示剩余3条评论
2个回答

5
这需要使用try catch块,因为您提到变量都是本地的,所以您可能只需将它们放在try catch块外面。 编辑 所以,现在我更详细地了解问题。我想我知道混淆出现的原因了。如果迭代超过最大值,您被告知抛出异常,这是可行的方法,但是现在您需要一种处理此异常项的方法。
那么,让我们看看您的原始代码:
public class Fibonacci {
private static final long MAX = 91;

public static long finonacciGetal(int n) {
        if (n > MAX || n < 0) throw new FibonacciException();
        else {

            long eerste = 0;
            long tweede = 1;
            long getal = 0;

            for (int i = 0; i < n; i++) {
                getal = eerste + tweede;
                eerste = tweede;
                tweede = getal;
            }
            return getal;
    }
}
}

这样已经很好了。现在,如果你看看抛出异常的那个案例,你会发现你的局部变量中没有任何值被计算。这是好事,因为这种异常意味着有人试图使用超出你允许范围的值调用此方法。为确保使用此类的人正在处理您的异常,一种方法是在方法声明中添加throws子句,如下所示:

public class Fibonacci {
private static final long MAX = 91;

public static long finonacciGetal(int n) throws FibonacciException {
        if (n > MAX || n < 0) throw new FibonacciException();
        else {

            long eerste = 0;
            long tweede = 1;
            long getal = 0;

            for (int i = 0; i < n; i++) {
                getal = eerste + tweede;
                eerste = tweede;
                tweede = getal;
            }
            return getal;
    }
}
}

那么,当有人像这样在主函数中使用它时:

public static void main(String[] args) {
    try{
        System.out.println(new Fibonacci().fibonacciGetal(92));
    }catch(FibonacciException e){
        System.out.println(e.getMessage());
    }
}

你会注意到,在使用它的方法中必须使用try/catch来处理这些情况,这是处理这些情况的正确方式。

还有没有可能保留我的本地变量?这是我收到的任务,我不认为我被允许编辑它们。 - Glenndisimo
@Glenndisimo 为什么你想要“保留我的本地变量”?你想要实现什么目标?我认为你可能对某些事情基本上感到困惑。 - ajb
@WillBD 这就是我最初的代码,但它返回错误的值。一旦抛出1个异常,程序应该停止。 - Glenndisimo
2
@Glenndisimo 我认为你的教授并不希望在抛出异常时方法保持“不变”。所以当你说“我不能对任务做任何更改”时,我相信这并不适用于发生异常的情况。如果你的教授希望该方法抛出异常并返回相同的结果,具有相同的局部变量值和其他所有内容,那么你的教授就是困惑的。 - ajb
不要忘记,OP的异常没有消息可打印。 - Radiodef
显示剩余3条评论

0

只需更新您的异常,使消息成为消息即可:

public class FibonacciException
extends ArithmeticException {

    public FibonacciException() {
        super("Max value surpassed");
    }
}

你的方法的调用者将会像这样做:

try {
    long f = finonacciGetal(-1);

} catch(FibonacciException fe) {

    // prints something like
    // "com.acme.FibonacciException: Max value surpassed"

    System.err.println(fe); 
}

现在它自动打印堆栈跟踪,因为您没有捕获它。当您捕获异常时,您可以决定如何处理它,这取决于您方法的调用者。您不必担心那部分内容。您的任务只是抛出异常。


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