Método alcançável?

6 respostas
D

Turma,

estou lendo o livro Java Efetivo do Joshua Bloch e não entendi um trecho:

Página 137 (versão em português - 2ª edição)

"... Esse código funciona, mas não é muito elegante. Ele não será compilado sem a instrução throw porque o final do método é tecnicamente alcançável, sem nunca ser alcançado [JLS, 14.2.1] ..."

Não entendi: "o final do método é tecnicamente alcançável, sem nunca ser alcançado".

Neste ponto, Joshua está tratando de um enum que possui o seguinte código:

public enum Operation {
        PLUS, MINUS, TIMES, DIVIDE;

        double apply (double x, double y) {
               switch (this) {
                      case PLUS: return x + y;
                      case MINUS: return x - y;
                      case TIMES: return x * y;
                      case DIVIDE: return x / y;
               }

               throw new AssertionError ("Unknow op: " + this);
        }
}

Procurei na Java Language Specification pela seção 14.2.1, mas não encontrei esta seção. Esta seção não existe. A seção 14.2 (http://docs.oracle.com/javase/specs/jls/se5.0/html/statements.html#14.2) contem apenas o seguinte:

14.2 Blocks
A block is a sequence of statements, local class declarations and local variable declaration statements within braces.

Block:
{ BlockStatementsopt }

BlockStatements:
BlockStatement
BlockStatements BlockStatement

BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement

A block is executed by executing each of the local variable declaration statements and other statements in order from first to last (left to right). If all of these block statements complete normally, then the block completes normally. If any of these block statements complete abruptly for any reason, then the block completes abruptly for the same reason.

Alguma dica?

Não sei se a tradução foi infeliz neste ponto, mas realmente não entendi.

Abraços,

Daniel Augusto

6 Respostas

diogozero

Creio que ele quis dizer que o final do método é “tecnicamente alcançável” por não ter problemas quanto a compilação do código.

Porém, esse trecho

throw new AssertionError ("Unknow op: " + this); nunca será alcançado porque você sempre vai passar uma operação válida (Somar, subtrair…)

renanjp

Quando você lança uma exceção todo o restante se torna Inalcançável (Unreachable code)…
EX:

public void ola() throws Exception{
	throw new Exception();
	System.out.println("ola");
}

Olhe este método…
Observe o erro de compilação…
Quando ele lança a exceção se interrompe o fluxo como se fosse um ?return?, ou seja, as linhas a baixo estão inalcançáveis (nunca serão executadas).

Espero que tenha ajudado…

renanjp

[quote=diogozero]Creio que ele quis dizer que o final do método é “tecnicamente alcançável” por não ter problemas quanto a compilação do código.

Porém, esse trecho

throw new AssertionError ("Unknow op: " + this);

Justo, agora entendi o que ele quis dizer…
Boua!!

D

Coloquei este código para funcionar e as conclusões que cheguei foram:

Quando ele diz que o código não funcionará sem o throw, realmente o compilador reclama da ausência de um retorno para o método apply (que deve retornar um double).

Fiz o teste e substitui o throw new AssertionError por um return 0; e passou a compilar. Poderia ser um return qualquer_coisa_double. Só que fica meio esquisito não acham?

Com esta substituição, entendi que apesar da instrução throw new AssertionError estar presente, ela nunca será executada pois o método apply irá retornar um resultado de acordo com o operador (PLUS, MINUS, TIMES, DIVIDE).

Pelo que entendi, o throw new AssertionError foi adicionado de forma a “enganar” o compilador que exige um retorno do método. O compilador não enxerga os returns que ficam dentro do switch e a adição do AssertionError “satisfaz” o compilador por um retorno no método.

Obrigado pelas explicações.

Atenciosamente,

Daniel Augusto

marciorodr0

Eu olho pra esse throw ai no final como uma segurança a mais…

Por exemplo se criar mais um item no enum e for passado para este método… vai dar um erro… e não só retornar um valor qualquer…

D

É isso mesmo.

Adicionei um novo operador e é lançada a exceção AssertionError, quando chamado o apply neste novo operador.

Agora realmente fez sentido a presença do AssertionError.

Obrigado a todos.

Atenciosamente,

Daniel Augusto

Criado 23 de julho de 2012
Ultima resposta 23 de jul. de 2012
Respostas 6
Participantes 4