Java throw关键字示例
在post try-catch块中,我们已经看到了一些异常示例,但是所有这些异常都是Java运行时抛出的。我们可以选择在Java代码中明确引发异常,可以使用Java中的throw语句来完成。
Java throw语句的一般形式
throw语句只需要一个参数。一个可抛出的对象。
throw throwableObj;
在这里throwableObj必须是Throwable类或者其任何子类的实例。
如何获得Throwable类实例
如果要显式引发异常,则可以通过两种方式获取此Throwable类实例:
- 我们可以使用new运算符创建实例。参见示例。
- 我们可以使用catch块的exception参数并重新抛出该异常。参见示例。
如果Java代码中有throw语句,则在遇到throw语句后立即停止执行。为匹配的异常类型检查最近的catch块,如果catch块具有匹配的异常类型,则该块处理引发的异常。如果找不到匹配的异常类型,则检查下一个较高的上下文,依此类推。
具有新异常实例的Throw语句示例
如上所述,在代码中引发异常的一种方法是使用new运算符创建异常实例。
public class ThrowDemo { public static void main(String[] args) { try{ if(args.length != 2){ throw new IllegalArgumentException("Two parameters should be passed"); } }catch(IllegalArgumentException exp){ System.out.println("Exception in the code " + exp.getMessage()); exp.printStackTrace(); } } }
输出:
Exception in the code Two parameters should be passed java.lang.IllegalArgumentException: Two parameters should be passed at com.theitroad.ThrowDemo.main(ThrowDemo.java:8)
在上面的代码中,如果未传递2个参数,则会引发异常。创建异常实例时使用的构造函数是采用String参数的构造函数。这样,我们可以通过明确的原因来抛出异常。异常类中有一个方法getMessage()方法,可用于显示该消息。
引发相同异常时的Java throw语句示例
我们还可以重新抛出在catch块中捕获的异常。这样做的常见原因之一是查看针对该特定异常是否抛出了异常处理程序。例如,如果我们有一个具有Exception作为异常类型的catch块,则它将捕获大多数异常,因为Exception在异常层次结构中较高。我们可以将该异常重新抛出以由具有特定异常类型的异常处理程序捕获。
public class ExceptionDemo { public static void main(String[] args) { ExceptionDemo ed = new ExceptionDemo(); try{ ed.division(7, 0); }catch(ArithmeticException exp){ System.out.println("Exception occurred while dividing" + exp.getMessage()); exp.printStackTrace(); } } private void division(int num1, int num2){ double result; try{ result = num1/num2; System.out.println("Result" + result); }catch(Exception exp){ System.out.println("Exception occurred while dividing" + exp.getMessage()); throw exp; } } }
输出:
Exception occurred while dividing/ by zero java.lang.ArithmeticException: / by zero at com.theitroad.ExceptionDemo.division(ExceptionDemo.java:18) at com.theitroad.ExceptionDemo.main(ExceptionDemo.java:8) Exception occurred while dividing/ by zero java.lang.ArithmeticException: / by zero at com.theitroad.ExceptionDemo.division(ExceptionDemo.java:18) at com.theitroad.ExceptionDemo.main(ExceptionDemo.java:8)
在上面的代码分割方法中,有一个带有Exception类参数的catch块。从那里我们将抛出捕获的异常。在调用方法中,它再次被具有参数ArithmeticException类型的catch块捕获。
抛出另一个异常
我们还可以使用Java throw关键字捕获一种类型的异常并重新抛出另一种类型的异常。实际上,当我们通过单独的层传播异常时,进行异常处理的最佳实践是这样做。这有助于保留代码的松散耦合。
例如,在数据库层中捕获了SQLException,让同一个异常传播到业务层毫无意义。在这种情况下,最好的办法是捕获SQLException(这是DAO层中的已检查异常),然后抛出另一个应传播到业务层的异常(未检查)。我们应该将原始异常实例作为参数发送。
catch(SQLException ex){ throw new RuntimeException("Error in DB layer", ex); }