详解Java编程中throw和throws子句的使用方法
Javathrow:异常的抛出
程序可以用throw语句抛出明确的异常。Throw语句的通常形式如下:
throwThrowableInstance;
这里,ThrowableInstance一定是Throwable类类型或Throwable子类类型的一个对象。简单类型,例如int或char,以及非Throwable类,例如String或Object,不能用作异常。有两种可以获得Throwable对象的方法:在catch子句中使用参数或者用new操作符创建。
程序执行在throw语句之后立即停止;后面的任何语句不被执行。最紧紧包围的try块用来检查它是否含有一个与异常类型匹配的catch语句。如果发现了匹配的块,控制转向该语句;如果没有发现,次包围的try块来检查,以此类推。如果没有发现匹配的catch块,默认异常处理程序中断程序的执行并且打印堆栈轨迹。
下面是一个创建并抛出异常的例子程序,与异常匹配的处理程序再把它抛出给外层的处理程序。
//Demonstratethrow. classThrowDemo{ staticvoiddemoproc(){ try{ thrownewNullPointerException("demo"); }catch(NullPointerExceptione){ System.out.println("Caughtinsidedemoproc."); throwe;//rethrowtheexception } } publicstaticvoidmain(Stringargs[]){ try{ demoproc(); }catch(NullPointerExceptione){ System.out.println("Recaught:"+e); } } }
该程序有两个机会处理相同的错误。首先,main()设立了一个异常关系然后调用demoproc()。demoproc()方法然后设立了另一个异常处理关系并且立即抛出一个新的NullPointerException实例,NullPointerException在下一行被捕获。异常于是被再次抛出。下面是输出结果:
Caughtinsidedemoproc. Recaught:java.lang.NullPointerException:demo
该程序还阐述了怎样创建Java的标准异常对象,特别注意下面这一行:
thrownewNullPointerException("demo");
这里,new用来构造一个NullPointerException实例。所有的Java内置的运行时异常有两个构造函数:一个没有参数,一个带有一个字符串参数。当用到第二种形式时,参数指定描述异常的字符串。如果对象用作print()或println()的参数时,该字符串被显示。这同样可以通过调用getMessage()来实现,getMessage()是由Throwable定义的。
Javathrows子句
如果一个方法可以导致一个异常但不处理它,它必须指定这种行为以使方法的调用者可以保护它们自己而不发生异常。做到这点你可以在方法声明中包含一个throws子句。一个throws子句列举了一个方法可能抛出的所有异常类型。这对于除Error或RuntimeException及它们子类以外类型的所有异常是必要的。一个方法可以抛出的所有其他类型的异常必须在throws子句中声明。如果不这样做,将会导致编译错误。
下面是包含一个throws子句的方法声明的通用形式:
typemethod-name(parameter-list)throwsexception-list{ //bodyofmethod }
这里,exception-list是该方法可以抛出的以有逗号分割的异常列表。
下面是一个不正确的例子。该例试图抛出一个它不能捕获的异常。因为程序没有指定一个throws子句来声明这一事实,程序将不会编译。
//Thisprogramcontainsanerrorandwillnotcompile. classThrowsDemo{ staticvoidthrowOne(){ System.out.println("InsidethrowOne."); thrownewIllegalAccessException("demo"); } publicstaticvoidmain(Stringargs[]){ throwOne(); } }
为编译该程序,需要改变两个地方。第一,需要声明throwOne()引发IllegalAccessException异常。第二,main()必须定义一个try/catch语句来捕获该异常。正确的例子如下:
//Thisisnowcorrect. classThrowsDemo{ staticvoidthrowOne()throwsIllegalAccessException{ System.out.println("InsidethrowOne."); thrownewIllegalAccessException("demo"); } publicstaticvoidmain(Stringargs[]){ try{ throwOne(); }catch(IllegalAccessExceptione){ System.out.println("Caught"+e); } } }
下面是例题的输出结果:
insidethrowOne caughtjava.lang.IllegalAccessException:demo