在Java catch块中,您如何知道哪个方法/行抛出异常?

时间:2016-01-16 00:04:34

标签: java exception try-catch

在try块中,我想执行两个函数。如果第一个失败则不执行第二个。我还想打印出哪个功能失败了。

请参阅以下代码。

try {
  a = func1();
  b = func2();  //won't execute if a failed
}
catch (Exception e) {
  //TODO: print a or b failed?
}

语言是否自然支持这种情况?

如果没有,以下是一个好习惯吗? (我无法想到它有什么不妥。但它让我感到担忧,因为我不记得在return中看到任何人使用catch。)

try {
  a = func1();
}
catch {
  //print: a failed
  return; //if a failed then skip the execution of b
}

try {
  b = func2();
}
catch {
  //print: b failed
}

编辑: 意见总结:

  1. 从两种方法中抛出不同的异常。

    • 在这种情况下,方法是由其他人编写的,我无法控制。
  2. e.printStackTrace()将打印行号和功能

    • 我想做的不仅仅是打印。更像是,如果失败,请执行以下代码。

5 个答案:

答案 0 :(得分:4)

你想要的是String methodName = e.getStackTrace()[0].getMethodName());

但这不是一个好习惯。标准方法是在日志记录框架中使用适当的方法记录异常,或者(如果编写控制台应用程序,Java的情况很少)将其打印到错误或标准输出或可选地打印到其他PrintStream,例如,使用printStackTrace(printStream)

但是在大​​多数情况下,您希望将异常传播到上层并通过适当的高级代码处理(或决定不处理它)。捕获这样的异常会导致令人讨厌的错误。 99%的情况下,从catch black返回也是一个非常糟糕的主意,因为异常表示方法的异常终止,而返回值则没有。

答案 1 :(得分:2)

as dev-null写道e.getStackTrace()可以提供帮助。但请注意,func1func2本身可能不会抛出异常,而是通过他们调用的其他方法抛出异常。因此,在点击func1func2之前,您需要遍历数组的所有元素。

在单独的try块中调用它们肯定是实践的,但它可能会变得很麻烦。

答案 2 :(得分:1)

这将有效:

String failedFunc = "func1";
try {
    a = func1();
    failedFunc = "func2";
    b = func2();  //won't execute if func1() failed
} catch (Exception e) {
    System.out.println("Func '" + failedFunc + "' failed: " + e);
}

当然,如果你所做的只是打印错误,那么打印堆栈跟踪将显示它确切的失败位置。但是,如果您需要failedFunc的值而没有完整的堆栈跟踪,则上述代码非常有用。

答案 3 :(得分:1)

如果抛出异常,则记录堆栈跟踪将通知您哪一行引发了异常。如果try / catch中的第一行抛出异常,则不会执行下一行。

答案 4 :(得分:1)

正如我在评论中所说,您可以使用e.printStackTrace()来确定Exception的原因。既然您表达了对不同行为的渴望,那么您有几个选择。您可以使用自定义func1编写两个本地函数来修饰您的func2Exception调用。像,

class Func1Exception extends Exception {
    public Func1Exception(Exception e) {
        super(e);
    }
}

class Func2Exception extends Exception {
    public Func2Exception(Exception e) {
        super(e);
    }
}

然后你可以编写像

这样的本地函数
private static Object func1Decorator() throws Func1Exception {
    try {
        return func1();
    } catch (Exception e) {
        throw new Func1Exception(e);
    }
}

private static Object func2Decorator() throws Func2Exception {
    try {
        return func2();
    } catch (Exception e) {
        throw new Func2Exception(e);
    }
}

然后你可以按照自己的意愿处理它们,

try {
    a = func1Decorator();
    b = func2Decorator(); // this still won't execute if a failed
} catch (Func1Exception e) {
    // a failed.
} catch (Func2Exception e) {
    // b failed.
}

如果您希望 a失败时func2能够运行,您可以使用finally块,

try {
    a = func1Decorator();
} catch (Func1Exception e) {
    // a failed.
} finally {
    try {
        b = func2Decorator(); // this will execute if a fails
    } catch (Func2Exception e) {
        // b failed.
    }
}