【发布时间】:2010-01-01 17:13:27
【问题描述】:
当你这样做时:
public class Blah {
public void doBlah() throws BlahException {
}
}
添加throws BlahException 的真正作用是什么?
它基本上是否将任何例外归为一类?即如果有异常,不管它是什么,总是使用BlahException抛出?
【问题讨论】:
当你这样做时:
public class Blah {
public void doBlah() throws BlahException {
}
}
添加throws BlahException 的真正作用是什么?
它基本上是否将任何例外归为一类?即如果有异常,不管它是什么,总是使用BlahException抛出?
【问题讨论】:
它告诉您的类的客户 DoBlah 方法可以抛出 BlahException 或 任何其他扩展它的异常。
如果它是一个已检查的异常,编译器将要求他们将对该方法的调用包装在一个 try/catch 块中。如果未选中,他们可以选择不捕获异常,但他们必须注意,如果不这样做,它将在调用堆栈中进一步冒泡。
它没有说明 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关键字,方法引发的异常无法在方法外处理。
不是吗?
【讨论】:
没有。 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类型的异常,而且这个异常既没有被捕获也没有被声明为抛出。
但是,下面的代码可以正常编译。
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();
}
}
}
本质上,你是在告诉编译器这个函数可能抛出一个不在函数内部处理的异常。这些类型的异常都是java.lang.Exception 的子类,被称为已检查异常。其他表示由程序本身的错误而不是由格式错误等条件引起的灾难性故障的异常是java.lang.RuntimeException 的子类,它们被称为未经检查的异常。简而言之,未经检查的异常可以在方法签名中没有throws 子句的情况下抛出,而任何检查的异常都必须在其中指明。
有关已检查与未检查异常的讨论,请参阅http://www.javapractices.com/topic/TopicAction.do?Id=129
【讨论】:
您的方法doBlah() 需要有可以throw BlahException 或BlahException 的任何子类的东西。这告诉doBlah() 的调用者通常要小心将代码包装在try-catch 中。
【讨论】: