JCIPのセクション6.3.2によると:
Runnableはかなり限定的な抽象化です。runは、値を返したり、チェックされた例外をスローしたりすることはできません。
run()
戻り型がvoidであるため、値を返すことはできませんが、チェックされた例外をスローできないのはなぜですか?
JCIPのセクション6.3.2によると:
Runnableはかなり限定的な抽象化です。runは、値を返したり、チェックされた例外をスローしたりすることはできません。
run()
戻り型がvoidであるため、値を返すことはできませんが、チェックされた例外をスローできないのはなぜですか?
最初のバージョンからチェック例外をスローするように宣言されておらず、変更するには危険すぎるため、チェック例外をスローすることはできません。
元々Runnable
はラップされたでのみ使用されてThread
いましたが、開発者は、にログを記録するのではなく、チェックされたすべての例外をキャッチして処理したいと考えていましたSystem.err
。
Callable
スローされた例外Executor
の結果をキャプチャできる場所に個々のタスクを追加できる場合に追加されました。Future
Callable
値を返し、オプションでチェックされた例外を宣言できるようになりました。
ところで:呼び出し可能オブジェクトからの戻りやチェックされた例外のスローを望まないと言うことができる1つの方法は、次のようなものを使用することです。
Callable<Void> callable = new Callable<Void>() {
public Void call() {
// do something
return null;
}
};
これは質問に対する答えではありません。むしろ、これは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();
}
}
これはクラスです-本当に古代の黒い帽子のJavaブードゥー。これを絶対に行わないでください。人々を感動させるパーティーを除いて。
run()
チェックされた例外をスローするように宣言されていないため、スローできません。チェックされた例外を宣言せずにスローすることはできません。
また、その例外をスローしない別のメソッドをオーバーライドまたは実装するメソッドで、チェックされた例外を宣言することはできません。したがって、の実装は、の実装に句をRunnable
単純に追加することはできません。throws
run()
チェックされた例外をいつでも安全にスローできません。
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
そうは言っても、やらないでください!;-)
Runnable Interfaceを見ると、void run()
メソッドがチェックされた例外をスローするものとして宣言されておらず、ThreadクラスがRunnableInterfaceを実装していることがわかります。
JLSによると、メソッドm1は、インターフェイス/スーパークラスで宣言されていない場合、例外をスローできません。
Runnableで署名voidrun()を保持する背後にある動機は、他のメソッドのように呼び出されることを意図しておらず、代わりにCPUスレッドスケジューラによって呼び出されるように設計されていることだと思います。もしそうなら、誰がその戻り値を受け取り、誰がこれによってスローされたチェック例外を処理するのか。UncaughtExceptionHandlerは、スレッドによってスローされたキャッチされなかった例外を処理するためにJava5.0で提供されました。Executor Frameworkは、戻り値またはスローされた例外(ExecutionExceptionのラッパー)をスレッド間で共有されるオブジェクト(外部クラスインスタンスなど)の状態として保存し、Futureの呼び出し元(他のスレッドで実行されている)にそれらを提供します。get()。