2011-06-10 198 views
1

我在Java中的一些方法抛出异常,如NoSuchElementException,IllegalArgumentException等,但使用这些方法时,这些异常似乎未被选中。换句话说,我的方法的调用者不需要对抛出这些异常的方法进行try/catch。我周围看来,它似乎是默认情况下的“检查”,只有错误是“未选中”。但不知何故,我抛出的例外也未被检查。真奇怪。抛出已检查的异常

如何确保当我的方法抛出异常时,调用者必须在编译时捕获异常?简单地说,我怎样才能抛出一个检查异常?

谢谢!

回答

6

只有RuntimeException及其子类没有选中。 (嗯,Error及其子类也是如此,但是你不应该混淆Error s)。你只需要做一个检查异常就可以确保它不会延伸RuntimeException

0

扩展RuntimeException的异常不必声明。

您可以声明方法:throws Exception或甚至throws Throwable并且必须处理(尽管不建议)。

3

是否检查异常是否为不是如何抛出或声明它,只取决于您选择的异常是否从RuntimeException派生。上面列出的那些都是从RuntimeException派生的,因此您的方法的客户端不需要捕获它们。

1

我认为你应该退后一步,学习背后的理论为什么要抛出一个检查异常与未检查的异常。关于异常的Java tutorial是一个很好的资源。

从有权Unchecked Exceptions — The Controversy页:

运行时异常表示是一个规划问题的结果,因此,该API的客户端代码不能合理地期望从中进行恢复或处理他们的问题任何方式。

2

检查Throwable的所有子类,除了Error和RuntimeException的子类外。 (你可以直接子类Throwable)

编译器检查这些异常,但是它们在运行时没有特殊的地方。即您可以在编译器不知道的情况下抛出一个checked异常,并且它将正常运行。

例如

public static void throwChecked(Throwable t) /* no throws clause */ { 
    Thread.currentThread().stop(t); 
} 

public static void main(String... args) /* no throws clause */ { 
    throwChecked(new Throwable()); 
} 

这可编译和打印Throwable,如您所期望的那样。

+0

此方法在十多年前不推荐使用,将在未来版本中删除。不应该被使用。 https://docs.oracle.com/javase/9​​/docs/api/java/lang/Thread.html#stop-java.lang.Throwable- – 2017-10-22 09:07:35

+0

@ Miha_x64它已在Java 8中禁用。还有其他方式做同样的事情,这个答案应该更新。 – 2017-10-22 10:41:04

1

看到这个hack,它可能会帮助(希望它不是OT)。

public class Test { 

    // No throws clause here 
    public static void main(String[] args) { 
     doThrow(new SQLException()); 
    } 

    static void doThrow(Exception e) { 
     Test.<RuntimeException> doThrow0(e); 
    } 

    @SuppressWarnings("unchecked") 
    static <E extends Exception> void doThrow0(Exception e) throws E { 
     throw (E) e; 
    } 
}