「JavaConcurrencyin Practice」を読んだとき、次のような文に気づきました。
Runnableはかなり限定的な抽象化です。runは値を返したり、チェックされた例外をスローしたりできません
成功は私の好奇心をかき立てました。なぜRunnableのrunメソッドはチェックされた例外をスローできないのですか?まず、Runnableクラスのコードを見てみましょう。
public interface Runnable {
public abstract void run();
}
runメソッドの定義により、例外がスローされていないことが確認できます。それを確認するために別の実験を行ってください。プログラムは次のとおりです。コンパイルでき、RuntimeExceptionは実行時に報告されますが、スローされたRuntimeExceptionがIOExceptionなどのチェックされた例外に置き換えられた場合、コンパイルされません。
abstract class AClass {
public static void main(String[] args){
Runnable r = new Runnable() {
public void run() throws RuntimeException{
throw new RuntimeException("rr");
}
};
new Thread(r).start();
}
}
一般的なルールを見つけるために、別の実験が行われました。
class Sick extends Exception{
}
class FeverSick extends Sick{
}
class JointSick extends Sick{
}
class Children extends People{
public void coldAir() throws FeverSick{
}
}
class Adults extends People{
public void coldAir() throws RuntimeException/*,Exception ,IOException */{
}
}
class Olds extends People{
public void coldAir() throws JointSick{
}
}
public class People {
public void coldAir() throws Sick {
}
}
結論は次のとおりです。サブクラスが親メソッドをオーバーライドする場合、チェックされた例外がスローされると、例外は親メソッドによってスローされる例外のサブクラス(または同じ種類)である必要があります。RuntimeExceptionはこの制限の対象ではありません。