java, если суперкласс использует try/catch, почему расширяющий класс не может переопределить метод суперкласса с бросками в определении метода и проверенными исключениями [дубликаты]

Prog 1: если мы используем Checked Exception, программа не скомпилируется

Здесь у класса Student есть метод «tt», который генерирует исключение ClassNotFoundException, которое является проверенным исключением в java.

Класс Test расширяет класс Student и переопределяет метод «tt». На этот раз вместо использования try/catch я пытаюсь использовать ключевое слово throws.

Результатом является сбой времени компиляции.

class Student{

public void tt(){

    try {
        throw new ClassNotFoundException();
    }
    catch(ClassNotFoundException e) {

    }
}
}
class Test extends Student {

public void tt() throws ClassNotFoundException{

}

}

Prog 2: Если мы используем Unchecked Exception, профиль компилируется и работает нормально.

В том же классе Student есть метод «tt», который генерирует исключение NullPointerException, которое является непроверенным исключением в java.

Класс Test расширяет класс Student и переопределяет метод «tt». На этот раз вместо использования try/catch я пытаюсь использовать ключевое слово throws.

Результат – успешный забег. Приведенная ниже программа работает без каких-либо проблем.

class Student{

public void tt(){

    try {
        throw new NullPointerException();
    }
    catch(NullPointerException e) {

    }
}
}
class Test extends Student {

public void tt() throws NullPointerException{

}

}

Любые выводы приветствуются. Спасибо!


person Pranav Kumar    schedule 26.12.2018    source источник
comment
Почему? Потому что в спецификации языка сказано, что переопределяющий метод не может объявлять исключения, которые не объявлял переопределяемый метод. И потому, что когда у меня есть ссылка на объект Student и я вызываю tt, не требуется try-catch. Теперь, если фактический объект был Test, что должно произойти? Это был бы беспорядок.   -  person Ole V.V.    schedule 26.12.2018


Ответы (2)


Предположим, у вас был этот код:

Student s = new Test ();
s.tt ();

Поскольку метод tt класса Student не имеет предложения throws, вам разрешено вызывать s.tt() без обработки каких-либо исключений.

Но если подкласс Student (в вашем случае Test) переопределяет tt и выдает проверенное исключение, вызывающая сторона должна обработать это исключение. Но вызывающая сторона не знает, что должна с этим справиться, поскольку в базовом классе нет предложения throws. Поэтому подклассу не разрешено добавлять throws пунктов проверенных исключений к методам, которые он переопределяет.

person Eran    schedule 26.12.2018
comment
Для такого очевидного дубликата не лучше ли закрыть, чем дать новый ответ? - person Ole V.V.; 26.12.2018
comment
Привет Эран, Спасибо за быстрый ответ. Но по какой причине он работает с непроверенными исключениями/исключениями времени выполнения. Обратитесь к программе 2 в вопросе. - person Pranav Kumar; 26.12.2018
comment
Непроверенные исключения @PranavKumar не нужно обрабатывать, поэтому вы всегда можете их генерировать (поскольку вызывающая сторона не должна знать о них). На самом деле вы можете сгенерировать исключение NullPointerException, даже если удалите предложение throws. - person Eran; 26.12.2018
comment
Потому что непроверенные исключения не нужно объявлять. Судя по сигнатуре метода, метод в суперклассе также мог выдать NullPointerException, поэтому подкласс не создает никаких новых исключений. - person Ole V.V.; 26.12.2018

Эффективная сигнатура переопределяемого метода должна быть такой же. Здесь эффективные средства, изменение типа возвращаемого значения, подклассы выброшенного исключения в сигнатуре метода.

person Harpreet Sandhu - TheRootCoder    schedule 26.12.2018
comment
За исключением того, что подклассу разрешено объявлять меньше типов исключений. Только не вводите. - person Ole V.V.; 26.12.2018
comment
Это неправда. При переопределении метода совершенно нормально изменить возвращаемый тип на подтип, удалить типы исключений или заменить типы исключений подтипами. - person Dawood ibn Kareem; 26.12.2018
comment
Я написал сферу действия. (Изменение типа возврата и исключений.) - person Harpreet Sandhu - TheRootCoder; 26.12.2018