Dúvida com uma Questão Sobre exceções

Boa noite a todos os amigos, neste meu primeiro post do ano volto aqui para pedir ajuda em uma questão que encontrei em um simulado:

class Master{
	String doFileStuff() throws FileNotFoundException{
		return "a";
	}
}
public class Slave extends Master{
	public static void main(String[] args) {
		String s = null;
		try{
			s = new Slave().doFileStuff();
		}catch(Exception x){
			s = "b";
		}
		System.out.println(s);
	}
	//o que, inserido independentemente aqui, irá compilar e produzir a saída b
}

Daí vem as opções:

A->  String doFileStuff(){return "b";}
B->  String doFileStuff() throws IOException{return "b";}
C->  String doFileStuff(int x) throws IOException{return "b";}
D->  String doFileStuff() throws FileNotFoundException{return "b";}
E->  String doFileStuff() throws NumberFormatException{return "b";}
F->  String doFileStuff() throws NumberFormatException,FileNotFoundException{return "b";}

Eu marquei as opções A e D, a primeira porque não está lançando nenhuma exceção nova verificada e a segunda por estar lançando a mesma exceção, uma das que lança IOException eu não marquei por ser uma exceção mais genérica e o método não pode lançar e a outra porque não há sobrescrita, mas o teste diz que minha resposta está errada, vocês poderiam por favor me ajudar? Obrigado desde já, e feliz 2012 a todos.

E qual a pergunta dessa questão?

Vc colocou as opções e não a pergunta.

Olá JakeFrog, cara, eu coloquei a pergunta como comentário no código, mas acredito já ter encontrado a resposta, NumberFormatException é uma exceção não verificada e portanto pode ser lançada pelo método que está sobrescrevendo, neste caso além das opções A e D, as opções E e F também compilam, fiz o que deveria ter feito antes de postar, fui olhar na documentação, só gostaria de me certificar se a minha conclusão está certa. valeu.

[quote=sidney.tavares]Boa noite a todos os amigos, neste meu primeiro post do ano volto aqui para pedir ajuda em uma questão que encontrei em um simulado:

class Master{
	String doFileStuff() throws FileNotFoundException{
		return "a";
	}
}
public class Slave extends Master{
	public static void main(String[] args) {
		String s = null;
		try{
			s = new Slave().doFileStuff();
		}catch(Exception x){
			s = "b";
		}
		System.out.println(s);
	}
	//o que, inserido independentemente aqui, irá compilar e produzir a saída b
}

Daí vem as opções:

A->  String doFileStuff(){return "b";}
B->  String doFileStuff() throws IOException{return "b";}
C->  String doFileStuff(int x) throws IOException{return "b";}
D->  String doFileStuff() throws FileNotFoundException{return "b";}
E->  String doFileStuff() throws NumberFormatException{return "b";}
F->  String doFileStuff() throws NumberFormatException,FileNotFoundException{return "b";}

Eu marquei as opções A e D, a primeira porque não está lançando nenhuma exceção nova verificada e a segunda por estar lançando a mesma exceção, uma das que lança IOException eu não marquei por ser uma exceção mais genérica e o método não pode lançar e a outra porque não há sobrescrita, mas o teste diz que minha resposta está errada, vocês poderiam por favor me ajudar? Obrigado desde já, e feliz 2012 a todos.[/quote]

Override é quando você usa a mesma assinatura de um método, mas varia a sua implementação. Assim, se você deseja fazer um override, não pode haver outras exception além das declaradas pelo método pai.

Bem, a letra A define um novo método, por causa da falta da FileNotFoundException. As letras B, D, E e F seguem o mesmo raciocínio. A única que muda é a letra C, pois você chama na main new Slave().doFileStuff(), sem passar qualquer parâmetro para o objeto. Assim, será chamado o método original, que foi herdado pela classe filha.

Espero ter ajudado!

As respostas certas são:
A
D
E
F

Explicação:

Quando fazer uma sobrescrita de um método que sinaliza uma exceção você deve lembrar:

[list]Pode lançar as mesmas checked exceptions que foi declarada no método original.[/list]
[list]Pode lançar uma parte dessas exceções.[/list]
[list]Pode lançar subclasses da exceção sinalizada.[/list]
[list]Pode lançar qualquer runtime exceptions.[/list]

[quote=joaoluizjoaquim]As respostas certas são:
A
D
E
F

Explicação:

Quando fazer uma sobrescrita de um método que sinaliza uma exceção você deve lembrar:

[list]Pode lançar as mesmas checked exceptions que foi declarada no método original.[/list]
[list]Pode lançar uma parte dessas exceções.[/list]
[list]Pode lançar subclasses da exceção sinalizada.[/list]
[list]Pode lançar qualquer runtime exceptions.[/list][/quote]

E a letra B?

Bom dia ECO2004,

A letra B esta incorreta porque o método sobrescrito não pode lançar uma exceção verificada nova ou mais abrangente do que o metodo original, neste caso IOException seria a exceção mais abrangente e deveria ter sido lancada na classe Master, acho que pra simplificar fica assim: FileNotFoundException e filha de IOException.

[quote=sidney.tavares]Bom dia ECO2004,

A letra B esta incorreta porque o método sobrescrito não pode lançar uma exceção verificada nova ou mais abrangente do que o metodo original, neste caso IOException seria a exceção mais abrangente e deveria ter sido lancada na classe Master, acho que pra simplificar fica assim: FileNotFoundException e filha de IOException.[/quote]

Esqueci que uma FileNotFoundException é derivada de uma IOException…

Uma correção…o que está acontecendo com a letra B é um overload seguida de um override…o override ocorre por que o método tem o mesmo tipo de retorno e parâmetro (nenhum, no caso), enquanto que o overload ocorre quando uma nova exceção é assinada no método. Nesse caso, o overload sobrescreveu o método da classe pai.

Override é sobrescrever. Overload é sobrecarregar.

Se eu estiver errado, me corrijam!

Eco2004,

Cara, acho que você ta errado, se fosse sobrecarga compilaria, nao compila exatamente por ser sobrescrita, ou override,o que define a assinatura do método seria a lista de argumentos, e neste caso essa lista não foi alterada, ou seja, o método não tem argumentos. Para ser sobrecarregado ele deveria estar declarado assim:

String doFileStuff(String f)throws IOException{
    	return "b";
    }

Abraco.

[quote=sidney.tavares]Eco2004,

Cara, acho que você ta errado, se fosse sobrecarga compilaria, nao compila exatamente por ser sobrescrita, ou override,o que define a assinatura do método seria a lista de argumentos, e neste caso essa lista não foi alterada, ou seja, o método não tem argumentos. Para ser sobrecarregado ele deveria estar declarado assim:

String doFileStuff(String f)throws IOException{
    	return "b";
    }

Abraco.[/quote]

@sidney.tavares

O método foi sobrescrito. Disse errado!
Um método é sobrecarregado quando somente o seu parâmetro muda, em quantidade, ordem ou tipo. O tipo de retorno nem entra.

Eu quis comprovar fazendo o seguinte. Pode-se notar que um objeto Slave recebe uma instância da classe Slave. Assim, primeiramente eu verifica se o método chamado se encontra em seu contexto (abrangendo os métodos herdados). Se eu criasse um objeto Master apontando para uma instância da classe Slave e depois invocasse o método doFileStuff(), primeiramente seria verificado se o método existe em Master para depois verificar se o mesmo foi override em Slave. Se fossem métodos diferentes e não o mesmo sobrescrito, ele invocaria o método da classe Master e depois iria ver que não existiria o mesmo sobrescrito em Slave e imprimiria “a”. Mas isso não ocorreu. Ele imprimiu “b” da classe filha, contantando que realmente uma mudança de exceção somente não faz o método mudar.

Eu só não sei o porquê de não ter aceitado uma exceção mais abrangente que a primeira. Você sabe o motivo?

Olá Eco2004

Bem, o motivo está na hierarquia, como IOException está acima de FileNotFoundExcepetion, a regra para sobrescrita de métodos diz que o método que sobrescreve não pode lançar uma exceção mais abrangente do que o método original, se isso acontecer o código não compila, não é que o método em si muda, mas uma regra da linguagem está sendo quebrada, esse assunto, sobrescrita e sobrecarga confunde mesmo, mas para essa questão em específico o que está sendo testado é se conhecemos as regras de sobrescrição e no caso da opção B esta regra está sendo quebrada, não sei se consegui me fazer entender, mas se ainda tiver dúvida estamos aí, abraço.

Está ok!

Obrigado.

[quote=sidney.tavares]Olá Eco2004

Bem, o motivo está na hierarquia, como IOException está acima de FileNotFoundExcepetion, a regra para sobrescrita de métodos diz que o método que sobrescreve não pode lançar uma exceção mais abrangente do que o método original, se isso acontecer o código não compila, não é que o método em si muda, mas uma regra da linguagem está sendo quebrada, esse assunto, sobrescrita e sobrecarga confunde mesmo, mas para essa questão em específico o que está sendo testado é se conhecemos as regras de sobrescrição e no caso da opção B esta regra está sendo quebrada, não sei se consegui me fazer entender, mas se ainda tiver dúvida estamos aí, abraço.[/quote]

simplificando, é uma regra sobre exceções, metodo sobrescrito não pode lançar exceção de tipo mais generico que o metodo de origem.