Почему это компилируется? Переопределяющий метод не подкласс исключения - PullRequest
4 голосов
/ 22 октября 2019

Мне трудно понять, почему следующий код компилируется, хотя он не является подклассом исключения:

class Test 
{
    public void run() throws IOException 
    {
        System.out.println("Test");
    }
}

class SubTest extends Test 
{
    //not a subclass of IOException, still compiles 
    public void run() throws RuntimeException 
    {
        System.out.println("Test from sub");
    }
}

class Sub2Test extends Test 
{
    //not a subclass of IOException, does not compile
    public void run() throws Exception  
    {
        System.out.println("Test from sub");
    }
}

Я понимаю, RuntimeException - это непроверенное исключение, но я думал, что правило былочто это должен быть подкласс родительского исключения?

Ответы [ 2 ]

7 голосов
/ 22 октября 2019

Представьте, что есть абонент, который звонит Test#run. В объявлении Test#run говорится, что он может выдать IOException, поэтому вызывающая сторона знает, что может перехватить и обработать его:

Test test = // it could be instance of SubTest of Sub2Test
try {
   test.run();
} catch (IOException e) {

}

Тогда все в порядке, если SubTest не выбрасывает IOExceptionвызывающий не пропустит ничего.

Но если вы бросите какой-нибудь проверенный Exception, такой как Sub2Test, так как вызывающий не узнает об этом до времени выполнения, вызываемый не сможет его перехватить и обработать. Так что это не должно быть скомпилировано.

3 голосов
/ 22 октября 2019

"Я понимаю, что RuntimeException - это непроверенное исключение, но я подумал, что правило заключается в том, что оно должно быть подклассом родительского исключения?"

То естьобщее правило, как указано в JLS в разделе §11.2. Проверка исключений во время компиляции, в которой говорится (выделено мое)

Предложение throws переопределяющего метода может не указывать, что этот метод приведет к выбрасыванию любого проверенного исключения который переопределенному методу не разрешается, в соответствии с предложением throws, throw ( §8.4.8.3 ).

Но это относится только к проверенным исключениям, и это также явноутверждает, что

Классы непроверенных исключений ( §11.1.1 ) освобождены от проверки во время компиляции.

Таким образом, компилятор собираетсяигнорировать тот факт, что RuntimeException не является подклассом IOException.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...