Java中exception的throws关键字
当你这样做:
public class Blah { public void doBlah() throws BlahException { } }
添加throws BlahException
真的有什么作用?
它基本上将任何exception分组到那个吗? 即如果有exception,无论它是什么,将始终使用BlahException
抛出?
它告诉您的类的客户端DoBlah方法可以抛出BlahException或任何其他扩展它的exception 。
如果它是一个已检查的exception,编译器将要求它们在try / catch块中包装对此方法的调用。 如果它未经检查,他们可以选择不捕获exception,但是他们必须要注意,如果它们没有,它将在调用堆栈中进一步冒泡。
它没有说明未经检查的exception,如NullPointException或错误。 那些也总是被抛出。 throws子句中不需要它们。
此代码显示了它的工作原理:
ExceptionDemo.java:
package exceptions; public class ExceptionDemo { public static void main(String[] args) { ExceptionDemo demo = new ExceptionDemo(); try { // Removing the try/catch will result in a compilation error demo.doChecked(); } catch (CheckedException e) { e.printStackTrace(); } // Note: Not inside a try/catch, in spite of the throws clause demo.doUnchecked(); } public void doChecked() throws CheckedException { System.out.println("doing something that may throw a checked exception"); } // Note: "throws" clause is unnecessary for an unchecked exception public void doUnchecked() throws UncheckedException { System.out.println("doing something that may throw an unchecked exception"); } }
CheckedException.java:
package exceptions; public class CheckedException extends Exception { public CheckedException() { super(); } public CheckedException(String message) { super(message); } public CheckedException(String message, Throwable cause) { super(message, cause); } public CheckedException(Throwable cause) { super(cause); } }
UncheckedException.java:
package exceptions; public class UncheckedException extends RuntimeException { public UncheckedException() { super(); } public UncheckedException(String message) { super(message); } public UncheckedException(String message, Throwable cause) { super(message, cause); } public UncheckedException(Throwable cause) { super(cause); } }
不, throws BlahException
子句告诉编译器你的函数可能会抛出一个BlahException并且这应该被调用者捕获。 例如:
class ExceptionThrower { void someFunction() { for(int i =0; i<10;i++) if(i==4) throw new Exception(); } public static void main(String args[]) { new ExceptionThrower().someFunction(); } }
此程序将无法编译,因为它可以抛出Exception
类型的Exception
,并且exception既没有被捕获也没有声明被抛出。
但是,以下代码将编译正常。
class ExceptionThrower { void someFunction() throws Exception { for(int i =0; i<10;i++) if(i==4) throw new Exception(); } public static void main(String args[]) { try { new ExceptionThrower().someFunction(); } catch(Exception e) { e.printStackTrace(); } } }
从本质上讲,您告诉编译器此函数可能会抛出一个未在函数内部处理的exception。 这些类型的exception都是java.lang.Exception
子类,称为检查exception 。 其他exception表示由程序本身的错误引起的灾难性故障,而不是由输入格式错误等条件引起的java.lang.RuntimeException
子类,这些exception称为未经检查的exception 。 简而言之,在方法签名中没有throws
子句时可以抛出未经检查的exception,而必须在那里指出任何已检查的exception。
有关已检查与未检查exception的讨论,请参阅http://www.javapractices.com/topic/TopicAction.do?Id=129
整个想法是没有throws
关键字,方法throws
的exception无法在方法之外处理。
不是吗?
你的方法doBlah()
需要有一些东西可以throw
BlahException
或BlahException
任何子类。 这告诉调用者doBlah()
通常要小心将代码包装在try-catch
。