Utilizando exceções de forma correta

Ponto polêmico da linguagem Java, as opiniões sobre as checked exceptions passaram de “avanço” pra “retrocesso” dentro da comunidade. Barry Ruzek faz uma avaliação e mostra alguns dos erros e acertos na criação das exeções do Java e teoriza um pouco sobre tipos de erros que acontecem nas aplicaçoes:

Effective Java Exceptions

Pra quem já viu o livro “Effective Java” nem tudo é novidade e eu também achei que dizer que IOException deveria ser uma exceção “unchecked” também não parece ser uma boa idéia, porque todas as exceções de rede herdam de IOException e normalmente você pode se recuperar delas (a não ser que seja realmente algo como um cabo desligado :P), mas no geral os comentários são muito bons.

Há mesmo excelentes dicas sobre isso no livro Effective Java, do Joshua Bloch (criador da Collections Framework e do typesafe enum pattern). Você também pode ver um resumo aqui:
http://br.geocities.com/vanessasabino/java/ej6.html

Quem puder, compre o livro. Realmente é muito bom.
Para ver alguns capítulos de exemplo, basta entrar no site do livro:

http://java.sun.com/docs/books/effective/

E clicar em Sample Chapters.

O problema do checked é q o pessoal sempre cria um jeitinho de quebra-lo. Por exemplo:

try {
obj.fazAlgumaCoisa();
} catch (Exception e) {
e.printStackTrace();
}

No caso acima, o sistema continua e APENAS é impresso o erro. (em vez de tratá-lo ou joga-lo pra frente)

Uma abordagem para lidar com essas situações é capturar Exception e lançar como uma RuntimeException.

Por exemplo:

try {
obj.fazAlgumaCoisa();
} catch (Exception e) {
throw new RuntimeException(e);
}

Dessa forma o sistema emite o erro e pára, o que é diferente do primeiro caso que só envia menssagem de erro e continua.

fica aqui a dica

t+

Muito bom artigo mas não entendi uma coisa. Pelo o que ele diz, erros de negocio devem ser capturados e tratados em quem chama, qualquer outro como rede, banco, etc viram runtime e passam até serem são tratados em um só local da aplicação. Não é isso?!
Se sim, la diz que as que no caso dessas excecoes de negocio poderia ser retornado um null ou um valor pra ser verifica o erro, mas já vai lançar a exceçao, como retornaria algo? Ou não lança a excecao e so retorna o valor, mas ai se qualquer erro retornasse null, quem chama não saberia qual foi o erro.
É isso mesmo ou entendi errado?
:?:

[quote=Duende Macabro]Se sim, la diz que as que no caso dessas excecoes de negocio poderia ser retornado um null ou um valor pra ser verifica o erro, mas já vai lançar a exceçao, como retornaria algo? Ou não lança a excecao e so retorna o valor, mas ai se qualquer erro retornasse null, quem chama não saberia qual foi o erro.
É isso mesmo ou entendi errado?
:?: [/quote]

Não é retornar um “null”, é ter um método de teste pra saber se a operação pode ser feita ou não. Imagine que você quer fazer uma transferência de uma conta pra outra, em vez de chamar logo o método de transferir, você vai primeiro chamar um método “temFundos()” pra ver se a conta tem fundos o suficiente pra poder executar a transação. Assim, você não precisa se preocupar tanto com as exeções.

Só lembrando, conforme ressaltado no Effective Java, usar essa forma não é apropriada caso o seu objeto seja acessado de maneira concorrente, e o método dependa de sincronização.

Ainda no exemplo, no caso de sistemas concorrentes, uma outra thread poderia alterar o estado da conta para sem fundos exatamente entre as chamadas de temFundos() e transferir().