IOException - erro de compilação misterioso

13 respostas
T
import java.io.*;

class A
{
	public void process() { System.out.print("A,");}
}

class B extends A
{
	public void process() throws IOException{
		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");}
	}
}

Ao compilar esse código, o seguinte erro é gerado:

java:10: process() in B cannot override process() in A; overridden method does not throw java.io.IOException
	public void process() throws IOException{
	            ^
1 error

Porém, eu não entendi qual o problema. O erro diz que "o método sobreescrito NÃO joga uma IOException". Mas ele faz exatamente isso! Quem não joga uma IOException é o método da classe pai (A neste caso)

Obrigado! :wink:

13 Respostas

B

Amigo você não pode sobrescrever um método que não lança exceções com uma exeção verificada…dê uma lidinha nas regras válidas de sobrescrita…

E

Pelo que to vendo o codigo que vc passou nao compila…vc nao pode lançar uma exceçao maior que a do método herdado…

V

isto funciona

import java.io.*;   
  
class A   
{   
    public void process() throws IOException { System.out.print("A,");}   
}   
  
class B extends A   
{   
    public void process() throws IOException{   
        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");}   
    }   
}

se um método na superclasse não lançar exceções verificadas o msm método não pode lançar exceções verificadas na subclasse

T

Essas regrinhas são fogo… vmsb11, a explicação para isso é por causa do polimorfismo também?

V

creio que sim TiagoTC, uma das regras para declarar exceções tem alguma relação com o polimorfismo
por exemplo se um método da superclasse lançar uma exceção verificada do tipo X, o método da subclasse só poderá lançar uma exceção do tipo X ou Y(desde que Y seja um subtipo de X),
por exemplo

//criando uma classe de exceção X
class MyException extends Exception { }

//criando uma classe de exceção Y extendendo X
class MySubException extends MyException { }

class Animal {
   //este método pode lançar uma exceção verificada X
   public void falar() throws MyException { }
}
public class Cachorro extends Animal {
  //aqui eu  poderia lançar uma execeção verificada Y desde que Y extenda X na superclasse
  //reparou que MySubException estende MyException
  public void falar() throws MySubException { }
   //aqui tb funcionaria porque eu estou lançando a msm exceção que no método da superclasse
   //public void falar() throws MyException { }
   //aqui tb funciona porq eu estou tentando lançar uma exceção não verificada
   //public void falar() throws NullPointerException { }

}

só ressaltando exceções verificadas são aquelas que herdam da classe Exception e exceções não verificadas são aquelas que herdam das classes Error e RuntimeException
editando
corrigi um pequeno erro do código acima.

E

Sim mas na classe cachorro ele poderia lançar um MyException tb, assim como MySubException.

V

sim, eu no código comentado tb ta dizendo isso.

E

vmsb no caso do NullPointerException funcionaria pq?

V

ela extende RuntimeException que extende Exception e pela regra as classes que extendem a classe RuntimeException são exceções não verificadas ai eu acho que o compilador internamente consegue separar oque é exceções verificadas e não verificadas.

E

hum ok, entao nao tem nada haver com hierarquia mesmo n…

E

entao se a superclass assina um método com exceçao verificada, a subclass pode assinar com qualquer nao verificada?

T

Exatamente! Para provar, olhe esta frase:

“The overriding method CAN throw any unchecked (runtime) exception, regardless of whether the overridden method declares the exception.”

:slight_smile:

J

O que acontece é que as RuntimeException não são conhecidas em tempo de compilação, se fosse necessário trycatch pra todas elas, seu código ficaria todo entre trycatchs.
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/RuntimeException.html

Vejas as classes que extedem RuntimeException: ArithmeticException, NullPointerException, ArrayStoreException, IndexOutOfBoundsExceptions.
Imagina usar trycatch pra acessar um objeto que poderia lançar uma NullPointerException, trycatch pra um cálculo simples, trycatch pra acessar e escrever num Array e por aí vai…

Criado 8 de janeiro de 2010
Ultima resposta 9 de jan. de 2010
Respostas 13
Participantes 5