这个方法无法抛出已检查异常,因为在第一个版本中它没有声明抛出已检查异常,而改变它太危险了。
最初Runnable
仅用于包装的Thread
中,假设开发人员想要捕获所有已检查的异常并处理它们,而不是将它们记录到System.err
中。
当你可以将单独的任务添加到Executor
中并在Future
中捕获结果和任何抛出的异常时,就会添加Callable
。
Callable
现在允许您返回值并且可选地声明已检查异常。
顺便说一下:您可以使用类似以下方式来表达不想从可调用对象中返回或抛出已检查异常的意思
Callable<Void> callable = new Callable<Void>() {
public Void call() {
// do something
return null;
}
};
run()
方法不能抛出已检查异常,因为其没有声明会抛出此类异常。未经声明的情况下,你不能抛出已检查异常。Runnable
接口的类不能简单地为其 run()
方法添加 throws
子句。这不是回答问题的答案,而是对 Lukas Eder 的答案 的跟进,展示了另一种将已检查异常走私到不允许静态使用的地方的方法。这取决于一个事实:如果使用 newInstance
调用一个无参数构造函数,则它抛出的任何已检查异常都会向上逃逸。
public class Thrower {
private static final ThreadLocal<Exception> toThrow = new ThreadLocal<Exception>();
public static void throwUnsafely(Exception e) {
try {
toThrow.set(e);
Thrower.class.newInstance();
} catch (InstantiationException f) {
throw new RuntimeException("unexpected exception while throwing expected exception", f);
} catch (IllegalAccessException f) {
throw new RuntimeException("unexpected exception while throwing expected exception", f);
} finally {
toThrow.remove();
}
}
private Thrower() throws Exception {
throw toThrow.get();
}
}
这是A级别的真正古老的黑帽Java巫术。永远不要这样做,除非在聚会上想给人留下印象。
void run()
方法没有声明抛出任何已检查异常,而您的Thread类实现了Runnable接口。
JLS指出,如果在接口/超类中没有声明,方法m1将不能抛出异常。你可以随时不安全地抛出已检查的异常:
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class UnsafeSample {
public void methodWithNoDeclaredExceptions( ) {
Unsafe unsafe = getUnsafe();
unsafe.throwException( new Exception( "this should be checked" ) );
}
private Unsafe getUnsafe() {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe) field.get(null);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
public static void main( String[] args ) {
new UnsafeSample().methodWithNoDeclaredExceptions();
}
}
http://java.dzone.com/articles/throwing-undeclared-checked.
另一个选择:public class Test {
public static void main(String[] args) {
doThrow(new SQLException());
}
public static void doThrow(Exception e) {
Test.<RuntimeException> doThrow0(e);
}
@SuppressWarnings("unchecked")
public static <E extends Exception> void doThrow0(Exception e) throws E {
throw (E) e;
}
}
这是在这里展示的:
http://java.dzone.com/articles/throw-checked-exceptions
话虽如此,不要这样做! ;-)
Unsafe
。从无参构造函数抛出的已检查异常会逃逸一个 newInstance
调用。我会添加一个答案... - Tom Anderson