Подкласс Scjp выдает исключение IOException

class A {
             public void process() { System.out.print("A,"); }
         }
public class B extends A
         {
             public void process() throws IOException  {   //LINE 23
             super.process();
             System.out.print("B,");
             throw new IOException();
          }

 public static void main(String[] args) {

 try { new B().process(); }

 catch (IOException e) { System.out.println("Exception"); }
 }
}

Этот вопрос из SCJP 6, в книге говорится, что компиляция завершится ошибкой из-за ошибки в строке 23. Но я узнал, что вы не можете генерировать более широкое исключение, когда переопределяете метод из родительского класса. В этом примере мой метод родительского класса не выдает никаких исключений, а мой закрытый метод выдает IOException, который является подклассом Exception. Тогда почему он не работает?

Более того, я считаю, что если мой метод родительского класса не выдает исключения, по умолчанию он считается (( public void process() throws Exception. )). Это правда??


person user2985842    schedule 11.03.2014    source источник


Ответы (3)


Ваше понимание неверно

public void process(){}

а также

public void process() throws Exception{}

не эквивалентны. то, что вы можете сказать, эквивалентно:

public void process() throws RuntimeException{}

по определению вы не можете генерировать более широкое исключение из переопределенного метода в подклассе. но вы всегда можете создать непроверенное исключение из любого метода.

Для лучшего понимания прочитайте

person Sanjeev    schedule 11.03.2014
comment
Я с тобой согласен. Но даже если я использую public void process(), возникает Exception{} в классе A. Программа не компилируется - person user2985842; 11.03.2014
comment
Да, потому что это не будет совместимо с вашим IOException при вызове super.process() - person Sanjeev; 11.03.2014

Более того, я считаю, что если мой метод родительского класса не выдает исключения, он по умолчанию считается ((public void process() throws Exception.)). Это правда??

Это неправда. Вы должны объявить каждое checked исключение, выдаваемое методом, независимо от того, находится ли оно в классе (конкретном или абстрактном) или в интерфейсе.

Однако вы можете по-прежнему генерировать непроверенные исключения и/или ошибки (т. е. RuntimeException и подклассы, Error и подклассы) из метода, не объявляющего генерирование каких-либо исключений (хотя вам действительно следует вообще воздерживаться от генерирования Error) .

См. спецификацию языка Java, раздел 11.2 для более подробной информации. Начало этого раздела гласит (выделено мной):

Язык программирования Java требует, чтобы программа содержала обработчики проверяемых исключений, которые могут возникнуть в результате выполнения метода или конструктора. Для каждого проверенного исключения, которое является возможным результатом, в предложении throws для метода (§8.4.6) или конструктора (§8.8.5) должен упоминаться класс этого исключения или один из суперклассов класса этого исключения (§ 11.2.3).

person fge    schedule 11.03.2014

да У вас должно быть исключение, вызванное методом процесса класса A

и исключение должно быть граничным, чем исключение класса B

это обязательно, потому что в случае polymorphism

if

A obj=new B();

now  

obj.process()

не будет вынужден обрабатывать исключение, но метод, который вызывается, фактически выдает исключение

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

person Nirbhay Mishra    schedule 11.03.2014