terça-feira, 16 de fevereiro de 2010

Quando as chamadas polimórficas mudam tudo...

Estudando p/ o exame SCJP, ao fazer uma revisão de assuntos dos primeiros capítulos antes de prosseguir, notei uma coisa que não foi abordada pelo livro.

Aparentemente, fazer a chamada polimórfica de um método declarado na interface geraria o mesmo resultado:
interface Doable {
public void doSomething();
}

class Okay implements Doable {
@Override

public void doSomething() {
System.out.println("Oi, sou o método doSomething subscrito em Okay.");
}

public static void main(String[] args) {
Okay o = new Okay();
Doable d = o;

// Aparentemente o comportamento é o mesmo.
d.doSomething(); // OK
o.doSomething(); // OK
}
}
Será, então, impresso:
Oi, sou o método doSomething subscrito em Okay.
Oi, sou o método doSomething subscrito em Okay.
Ora, basta declarar o lançamento de exceções na declaração do método "doSomething()" da interface que tudo muda. Veja:
class BoringHolidayException extends Exception {}

interface Doable {

public void doSomething() throws BoringHolidayException;
}

class Okay implements Doable {
// Não declara a exceção BoringHolidayException.
@Override
public void doSomething() {
System.out.println("Oi, sou o método doSomething subscrito em Okay.");
}

public static void main(String[] args) {
Okay o = new Okay();
Doable d = o;

// Como a declarção de doSomething() na interface
// declara lançar a
exceção BoringHolidayException,
// a chamada polimórfica do método
através de uma
// referência à interface exigirá tratamento das exceções.

d.doSomething(); // Erro em tempo de compilação.

// Enquanto chamar o método diretamente por uma
// referência Okay não irá lançar a exceção, uma
// vez que, propositalmente, o método subscritor
// não lança nenhuma exceção.
o.doSomething(); // OK. Sem problemas.
}
}

O que já se sabe (se você também já leu o capítulo 1 do mencionado livro) é que duas das regras de subscrição são:
  1. não declarar exceções mais abrangentes e;
  2. não declarar novas exceções no método subscritor.
Embora você nem precise declarar qualquer exceção declarada pelo método subscrito, nunca faça nenhuma dessas duas coisas.

Então, neste caso, é necessário tratar a exceção declarada pela chamada polimórfica de doSomething(), mas não é necessário se preocupar pela chamada a partir da referência Okay.

Certo! Fiz esse post, porque sei que a SCJP adora pegadinhas desse tipo, então, tendo escrito aqui, não vou esquecer na hora da prova :ô) e, quem sabe, algum dia, alguém se preocupe em pesquisar isso no Google...

Nenhum comentário:

Postar um comentário