我从未使用过“throws”子句,今天有一个朋友告诉我,在方法声明中必须指定方法可能抛出的异常。然而,我一直在使用异常而没有问题,也没有这样做,那么,如果实际上需要,为什么需要它?
Java有两种不同类型的异常:checked 异常和 unchecked 异常。
Unchecked异常是RuntimeException子类,你不需要添加throws声明。所有其他异常都必须在方法体中处理,可以使用try/catch语句或者使用throws声明。
未经处理的异常示例:IllegalArgumentException,有时用于通知调用了带有非法参数的方法。无需添加 throws。
已处理的异常示例:IOException,某些来自java.io包的方法可能会抛出该异常。要么使用try/catch,要么在方法声明中添加throws IOException
并将异常处理委托给方法调用者。
public static void sleep(long millis) throws InterruptedException
所以如果你想在主方法中调用它,你必须要捕获它:
public static void main(String args[]) {
try {
Thread.sleep(1000);
} catch(InterruptedException ie) {
System.out.println("Opps!");
}
}
或者让该方法也声明它抛出一个异常:
public static void main(String args[]) throws InterruptedException {
Thread.sleep(1000);
}
InterruptedException
,因为throws
位于main()
函数上。如果发生其中一个,则程序将突然结束。 - Antonclass SneakyThrowTask implements Runnable {
public void run() {
throwSneakily(new IOException());
}
private static RuntimeException throwSneakily(Throwable ex) {
return unsafeCastAndRethrow(ex);
}
@SuppressWarnings("unchecked")
private static <X extends Throwable>X unsafeCastAndRethrow(Throwable ex) throws X {
throw (X) ex;
}
}
你可以这样调用它:
public static void main(String[] args) {
try {
new SneakyThrowTask().run();
} catch (RuntimeException ex) {
LOGGER.log(ex);
}
}
这个异常不会被记录。而且因为它是一个已检查的异常,你不能写出这样的代码:
public static void main(String[] args) {
try {
new SneakyThrowTask().run();
} catch (RuntimeException ex) {
LOGGER.log(ex);
} catch (IOException ex) {
LOGGER.log(ex); // Error: unreachable code
}
}
我很确定,如果你试图抛出一个已检查的异常,并且没有声明该方法抛出该类型的异常,代码甚至无法编译(现在正在检查)。
编辑,如果你尝试一些简单的东西,比如:
public static void main(String[] args) {
throw new Exception("bad");
}
您遇到了编译错误。
具体来说,如果您调用一个声明为抛出异常的方法,则必须尝试/捕获该方法调用,或声明您的方法会抛出这些异常。
throws
关键字用于将异常抛给另一个方法。throws
关键字让编译器处理可能发生的异常。throws
关键字在方法运行时处理它。Java throws关键字
throws
关键字用于声明异常。throws
后跟类名。throws
传播已检查异常。throws
示例:
void m()throws ArithmeticException{
//method code
}