Checked e unchecked exceptions nas camadas

55 respostas
B

Lendo o Mundo Java 33, sobre EJBs e Spring, na parte de controle de transações, fala que ambas as tecnologias fazem rollback da transação quando encontram unchecked exceptions, mas com as checked deixam rolar, supõem que o desenvolvedor queria que isso aconteça.

Fiquei pensando no caso de uma exceção na camada de persistência, como uma SQL ou IOException, normalmente não são esperadas pela aplicação.

A camada deveria tratar esses erros e transformá-los em erros do sistema quando a requisição voltar para a camada que a chamou? Acho meio infeliz dar um catch e um throw logo depois só pra transformar a exceção. O que tem de “checado” numa exceção dessas?

55 Respostas

Andre_Fonseca

Bruno Laturner:
Lendo o Mundo Java 33, sobre EJBs e Spring, na parte de controle de transações, fala que ambas as tecnologias fazem rollback da transação quando encontram unchecked exceptions, mas com as checked deixam rolar, supõem que o desenvolvedor queria que isso aconteça.

Fiquei pensando no caso de uma exceção na camada de persistência, como uma SQL ou IOException, normalmente não são esperadas pela aplicação.

A camada deveria tratar esses erros e transformá-los em erros do sistema quando a requisição voltar para a camada que a chamou? Acho meio infeliz dar um catch e um throw logo depois só pra transformar a exceção. O que tem de “checado” numa exceção dessas?

oi

aqui o cara que organizou o tratamento de excessões pensou que devemos sempre tratar todas as excessões checked possíveis e só em ultimo caso lançar uma unchecked

por exemplo, na camada DAO, eu teria algo assim

try { // consulta aqui } catch(NonUniqueResultException e) { return null; } catch(EntityNotFoundException e) { return null; } catch(HibernateException e) { logger.log(Level.SEVERE, e.getMessage()+"\n"+e); throw new RuntimeException(e); }

assim eu consigo garantir que se um runtime ocorrer é porque eu não encontrei a entidade ou ela não era única… na minha opinião, quanto menos unchecked você retornar, principalmente para uma aplicação J2EE, melhor

abs

rodrigo_gomes

Olá Bruno,

Esse é um bom ponto. Muitos consideram que essas exceptions (SQL, IO, por exemplo), não deveriam ser checadas. É um erro de projeto da linguagem.

Por isso, somos praticamente obrigados a fazer o que você falou. Tratar para transformar.

[]´s

B

Olá Bruno,

Esse é um bom ponto. Muitos consideram que essas exceptions (SQL, IO, por exemplo), não deveriam ser checadas. É um erro de projeto da linguagem.

Por isso, somos praticamente obrigados a fazer o que você falou. Tratar para transformar.

[]´s

É, tava pensando a mesma coisa, erro de projeto. Antes de ver a revista já até tinha lido um pouco sobre o assunto, em especial a Trilogia de Tratamento das exceções no Java do Luca (Parte 1 - Parte 2 - Parte 3).

É… complicado.

O Sérgio também tem vários artigos:
Exceções: Conceitos
Exceções: Boas práticas, más práticas
Exceções: Classe Utilitárias

Li um pouco na parte de Boas práticas, em Camadas e exceções

Bem, é a regra de que cada camada sabe tratar o que vem de baixo, seja retorno ou exceção, enquanto a que tá em baixo nem sabe que a de cima existe, então mesmo junto com essas novas regras de un/checked exceptions que outros frameworks usam, parece que tem q tratar tudo. Ou pelo menos transformar mesmo.

le-silva

Um ou dois tostões sobre o assunto…

http://leandrosilva.com.br/2008/08/12/cuidado-com-suas-excecoes

sergiotaborda

Bruno Laturner:

O Sérgio também tem vários artigos:
Exceções: Conceitos
Exceções: Boas práticas, más práticas
Exceções: Classe Utilitárias

Li um pouco na parte de Boas práticas, em Camadas e exceções

Bem, é a regra de que cada camada sabe tratar o que vem de baixo, seja retorno ou exceção, enquanto a que está em baixo nem sabe que a de cima existe, então mesmo junto com essas novas regras de un/checked exceptions que outros frameworks usam, parece que tem q tratar tudo. Ou pelo menos transformar mesmo.

Em inglês existe o termo “handle” (manipular) que é diferente de resolver.
Quando uma camada recebe uma exceção da camada inferior que ela não sabe resolver, mesmo assim ela têm que a manipular (handle). Em bom protugues, ela tem que fazer o try-catch. Mas isso apenas para a encapsular em uma outra Exceção da própria camada.

Por exemplo, quando vc comunica com o banco de dados via jdbc a exceção que é retornada é SQLException, sempre. Mesmo quando o erro é um IOException ( por exemplo, connectino timeout).

A dificuldade do encapsulamento advém do fato que simplesmente jogar todas as exceções das camadas inferirors no mesmo bolo não ajuda nada. ( por exemplo um SQLException de “sem conexão” deveria ser um exception de uma classe filha de SQLException). Seguindo a boa prática “Seja especifico” vc deve encapsular as exceções mais baixas em exceções da camada mas de forma categorizada. Todas elas herdam da exceção “mãe” da camada mas são mais especificas.

Por exemplo, numa camada de acesso a dados genérica poderíamos ter a exceção mae “DataAcessException” e como filhas poderíamos ter “ConnectionException” , “DatabaseNotFoundException” , “AutenticationException” , “DuplicateRegistryException” e “ConcurrencyException”. Todas elas são DataAcessException, mas todas significam erros de categorias diferentes.

finalmente as classe de exceção mãe deve ser filha de RuntimeException. Apenas deve ser filha de Exception se a camada representa algum subsistema fora do escopo da aplicação. ( por exemplo IOException é checked porque representa o o subsistema de arquivos do OS e a SQLException o subsistema de banco de dados)

Emerson_Macedo

Eu sou daqueles que acham que as Checked Exceptions do Java nunca deveriam existir pois mais atrapalham que ajudam. De qualquer forma isso é opinião e há controvérsias.

victorwss

Eu discordo. Acho que checked exceptions são importantes, apenas foram usadas da forma errada desde o começo da linguagem.

Há uma RFE que acho legal atacando exatamente este problema da linguagem:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6534270

ASOBrasil

victorwss:

Eu discordo. Acho que checked exceptions são importantes, apenas foram usadas da forma errada desde o começo da linguagem.

Concordo plenamente!

O pessoal usa certas coisas de maneira exagerada/errada e com isso aquilo que foi usado dessa forma é visto como uma porcaria, etc

Emerson_Macedo

Eu discordo. Acho que checked exceptions são importantes, apenas foram usadas da forma errada desde o começo da linguagem.

Há uma RFE que acho legal atacando exatamente este problema da linguagem:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6534270
Se você acha tão importante, apresente aqui um exemplo de uma situação que não seja possível resolver com unchecked exceptions ou seja necessário muito trabalho para alcançar o mesmo resultado.

ASOBrasil:
victorwss:

Eu discordo. Acho que checked exceptions são importantes, apenas foram usadas da forma errada desde o começo da linguagem.

Concordo plenamente!

O pessoal usa certas coisas de maneira exagerada/errada e com isso aquilo que foi usado dessa forma é visto como uma porcaria, etc


A questão aqui não foi usar de maneira errada, o que eu concordo que aconteceu bastante, mas a questão é que é inútil a existência das checked exceptions, mais uma vez na minha opinião. Caso você ache o contrário, apresente algum bom argumento para tal, assim como pedi ao colega acima.

E pra finalizar, eu posso tratar uma unchecked exception se eu quiser, eu só não sou forçado a faze-lo …

[]s

peczenyj

Ok, como vc lidaria se SQLException fosse unchecked?

victorwss
Emerson Macedo:
...

Quer um bom argumento!? Um exemplo!? Então vamos lá:

Que tal o InvocationTargetException dos métodos de reflection? Qualquer método chamdo por reflection pode lançar uma exceção, e simplesmente lançá-la para cima de qualquer jeito pode ser desastroso (afinal, você normalmente não sabe o que significa essa exceção). Assumir que o método nunca falhará normalmente significa uma falha de projeto, logo nada mais normal do que ser obrigado a tratar a exceção.

Um outro exemplo (usando aquela cláusula suppresses sugerida na RFE):
/**
 * Liga o aparelho que mede a incidência de luz solar
 * @throws EstaChovendoException Se estiver chovendo, o aparelho detecta isso
 * e retorna um status de falha indicando chuva.
 */
public void ligarAparelhoLuzSolar()
        suppresses IOException, EstaDeNoiteException
        throws EstaChovendoException
{
    // Se ocorrer uma falha de comunicação, não há muito o que fazer.
    // Lança o IOException não verificado.

    // Se for de noite, isso é um erro de programação,
    // deve-se verificar se não é noite antes de chamar este método.

    // Mas, quem chamar este método, deve esperar uma possível falha porque
    // esteja chovendo. Não podemos separar isso em um método estaChovendo()
    // porque a comunicação com o aparelho é muito cara.
}
Emerson_Macedo

Ok, como vc lidaria se SQLException fosse unchecked?
Já experimentou um Try-Cath? Bem basico e funciona que é uma beleza.

Você não acha mais simples tratar o que for necessário, ao invés de tentar ignorar o que você não quer tratar?

peczenyj

Ok, como vc lidaria se SQLException fosse unchecked?
Já experimentou um Try-Cath? Bem basico e funciona que é uma beleza.

Sim, mas ai eu opto por faze-lo: o compilador não me obriga.

Emerson_Macedo

Ok, como vc lidaria se SQLException fosse unchecked?
Já experimentou um Try-Cath? Bem basico e funciona que é uma beleza.

Sim, mas ai eu opto por faze-lo: o compilador não me obriga.
Vamos imaginar a seguinte cenário:

  • Objeto A envia uma mensagem ao Objeto B.
  • Objeto B retorna uma exception para o Objeto A como resposta a sua mensagem.

Eu suponho que o Objeto A que tenha a noção se esse erro ele quer/vai/precisa tratar de alguma forma. Portanto, me parece mais lógico que ele não seja obrigado a tratar. Caso contrário, O Objeto que recebeu a mensagem (no caso Objeto B) está tomando uma decisão que não lhe cabe(ou se preferir, o Objeto B está impondo uma decisão ao Objeto A).

peczenyj

Mas nesse caso o objeto A sabe do comportamento do objeto B pelo contrato e B parece ser incapaz de tratar um eventual erro, sem falar que B poderia ser, então, refatorado para B’ e trabalhar como vc achar melhor. Enfim é só uma observação.

Emerson_Macedo

Sim, eu entendi o que você quis dizer, mas qual seria o outro caso?

ASOBrasil

Emerson Macedo:

Vamos imaginar a seguinte cenário:

  • Objeto A envia uma mensagem ao Objeto B.
  • Objeto B retorna uma exception para o Objeto A como resposta a sua mensagem.

Eu suponho que o Objeto A que tenha a noção se esse erro ele quer/vai/precisa tratar de alguma forma. Portanto, me parece mais lógico que ele não seja obrigado a tratar. Caso contrário, O Objeto que recebeu a mensagem (no caso Objeto B) está tomando uma decisão que não lhe cabe(ou se preferir, o Objeto B está impondo uma decisão ao Objeto A).

Exatamente como o peczenyj falou, você coloca checked exceptions se você quiser! E se eu definir que o método que chamar a minha implementação deva tratar aquela exception então eu posso definir explicitamente e pronto! Entendeu que o negócio é opcional? A linguagem é aberta para isso e ela permite que cada pessoa trabalhe da maneira que achar melhor. Assim como você pode deixar tudo como “unchecked” porque você acha que é a melhor solução.

Rubem_Azenha

SQLException é um típico caso em que a API não foi bem projetada. Erros como SQLException, HibernateException, IOException, e etc são erros que não tem como ser remediado e geralmente o usuário do sistema não tem controle sobre a situação que gerou o erro, diferente de DataDeVencimentoInvalidaException ou DataSelecionaEhDiaUtilException (nome horrivel, eu admito).

Checked exceptions não devem ser tratadas na maioria dos casos, se você esta num ambiente “gerenciado” deixe seu application server\servlet container logar a exceção, configure o logger do servidor de forma correta e coerente com a forma como sua equipe lida com erros em produção e mostre uma tela de erro feliz para o usuário.

Emerson_Macedo

ASOBrasil:
Emerson Macedo:

Vamos imaginar a seguinte cenário:

  • Objeto A envia uma mensagem ao Objeto B.
  • Objeto B retorna uma exception para o Objeto A como resposta a sua mensagem.

Eu suponho que o Objeto A que tenha a noção se esse erro ele quer/vai/precisa tratar de alguma forma. Portanto, me parece mais lógico que ele não seja obrigado a tratar. Caso contrário, O Objeto que recebeu a mensagem (no caso Objeto B) está tomando uma decisão que não lhe cabe(ou se preferir, o Objeto B está impondo uma decisão ao Objeto A).

Exatamente como o peczenyj falou, você coloca checked exceptions se você quiser! E se eu definir que o método que chamar a minha implementação deva tratar aquela exception então eu posso definir explicitamente e pronto! Entendeu que o negócio é opcional? A linguagem é aberta para isso e ela permite que cada pessoa trabalhe da maneira que achar melhor. Assim como você pode deixar tudo como “unchecked” porque você acha que é a melhor solução.


Curioso é você definir que quem manda mensagem para teu objeto deva tratar alguma coisa. Eu acho isso péssimo. Acho muito mais lógico eu notifica-lo que algum problema aconteceu (i.e. lançando uma exception) e ele decidir qual ação vai tomar dado a mensagem de retorno. É o caso da SQLException. Quem a criou “definou” que agente tinha que tratar e no final das contas agente viu no que deu.

ASOBrasil

Emerson Macedo:

Curioso é você definir que quem manda mensagem para teu objeto deva tratar alguma coisa. Eu acho isso péssimo. Acho muito mais lógico eu notifica-lo que algum problema aconteceu (i.e. lançando uma exception) e ele decidir qual ação vai tomar dado a mensagem de retorno. É o caso da SQLException. Quem a criou “definou” que agente tinha que tratar e no final das contas agente viu no que deu.

Acho que nossa discussão entrou em um loop aqui. :slight_smile: Concordo com o que o Rubem disse. SQLException não é um bom exemplo e não acho que deve ser uma checked exception.

Rubem_Azenha

Emerson Macedo:

Curioso é você definir que quem manda mensagem para teu objeto deva tratar alguma coisa. Eu acho isso péssimo. Acho muito mais lógico eu notifica-lo que algum problema aconteceu (i.e. lançando uma exception) e ele decidir qual ação vai tomar dado a mensagem de retorno. É o caso da SQLException. Quem a criou “definou” que agente tinha que tratar e no final das contas agente viu no que deu.

Hum, tem o outro lado da moeda também… Por um lado checked exceptions tira a liberdade de quem usa a classe pois obriga a tratar a excessão, por outro lado se não tiver checked exceptions o autor da classe não tem nenhum mecanismo para obrigar quem usa a sua classe a tratar uma determinada excessão que ele julga importante ser tratada.

victorwss

O negócio é o seguinte:

Método A pode lançar exception X ocasionalmente. Vamos supor que o lançamento de X não corresponde a um erro de programação e nem a alguma falha catastrófica irrecuperável e que seja algo que possa ser efetivamente tratado de uma forma que não seja simplesmente “gere um log” ou “mostre uma mensagem para o usuário”. Ou seja, algo que cai bem no conceito de uma exceção verificada.

Chamar o método A e não tratar um possível X é um erro de programação. Logo, seria bom que o compilador te forçasse a tratar.

Por outro lado, se X for unchecked, é muito fácil se esquecer de tratar X corretamente. E isso é muito pior do que ter que encapsular em outras exceções ou coisas assim.

Ou pior, vamos supor que você pode ter DataDeVencimentoInvalidaException sugerido pelo Rubem. Vamos supor que ela é unchecked, daí você chama um método que lança esse troço e você nem sabia que isso podia ser lançado.

Exceções não checadas correspondem a falhas catastróficas e erros de programação. As outras, devem ser tratadas adequadamente, mesmo que isso exija cláusulas catch bem chatas e repetitivas. Se não houvesse checked exceptions, mesmo as falhas normais e esperadas poderiam compremeter a aplicação por não serem tratadas corretamente. E frequentemente vemos problemas por ter exceções que são esperadas serem empacotadas em unchecked exception ou herdarem de RuntimeException.

C# não tem checked exception. Lá é comum o problema do tipo “ué, eu não sabia que esse método podia lançar essa exceção.”

Emerson_Macedo

Rubem Azenha:
Emerson Macedo:

Curioso é você definir que quem manda mensagem para teu objeto deva tratar alguma coisa. Eu acho isso péssimo. Acho muito mais lógico eu notifica-lo que algum problema aconteceu (i.e. lançando uma exception) e ele decidir qual ação vai tomar dado a mensagem de retorno. É o caso da SQLException. Quem a criou “definou” que agente tinha que tratar e no final das contas agente viu no que deu.

Hum, tem o outro lado da moeda também… Por um lado checked exceptions tira a liberdade de quem usa a classe pois obriga a tratar a excessão, por outro lado se não tiver checked exceptions o autor da classe não tem nenhum mecanismo para obrigar quem usa a sua classe a tratar uma determinada excessão que ele julga importante ser tratada.


Realmente entramos em loop. Você acha que um objeto pode obrigar seu cliente a tratar uma exception. Eu já acho que o cliente que mandou a mensagem ao objeto e recebeu esse retorno deve decidir o que fazer.

Se você tiver testes automatizados (e.g. unitarios, integrados e funcionais), certamente não se esquecerá de tratar quando for necessário.

victorwss

Se você tiver testes automatizados (e.g. unitarios, integrados e funcionais), certamente não se esquecerá de tratar quando for necessário.

Seguindo isso que você disse, poderíamos tirar todas as verificações de corretude que o compilador faz e deixar tudo isso ao cargo do programador e de seus testes unitários/funcionais/whatever.

Rubem_Azenha

Aí é que esta a beleza da computação :slight_smile:

Eu prefiro ter X e eu preferir não usar X do que eu querer usar X mas não poder usar X por que a linguagem não tem X.

Depende… ter testes não garante que o teste faz a validação adequada.
Concordo que de forma alguma checked exceptions substituem ou diminuem a importância de testes, mas elas pelo menos dão um feedback mais rápido.

sergiotaborda

Rubem Azenha:
peczenyj:

Ok, como vc lidaria se SQLException fosse unchecked?

SQLException é um típico caso em que a API não foi bem projetada. Erros como SQLException, HibernateException, IOException, e etc são erros que não tem como ser remediado e geralmente o usuário do sistema não tem controle sobre a situação que gerou o erro, diferente de DataDeVencimentoInvalidaException ou DataSelecionaEhDiaUtilException (nome horrivel, eu admito).

Remediar o problema não tem nada a haver com ser verificada ou não. Não é porque a exceção é verificada que significa que vc pode resolver o problemas. E também não é verdade em exceções não-verificadas.

A diferença entre os dois tipos é conceptual, logo não faz sentido discutir se seria possivel usar java apenas com exceções não-verificadas. É possivel. Tanto é possivel que exceções verificadas só existem em java. Em outras linguagens ninguem sabe o que é isso.

Exceções verificadas são uteis porque obrigam o caller ( quem chama o método) a lidar ( handle, manipular) com a exceção explicitamente. Ou seja, o programador não tem como não saber que ali ha o lançamento de uma exceção.
Isto é particularmente util quando vc está criando frameworks e /ou API de camada. Quando o caller invoca a camada /framework ele perde o controlo. Nesse caso a camada abaixo tem que vigiar que é bem usada. Tal como um método verifica se argumentos não são nulos e estão dentro do esperado, também o mesmo tem que ser feito para exceções. Este tipo de API tem que forçar o caller a lidar com a exceção de forma que lidar com a exceção faz parte do contrato. É chato é, mas é util ? sim. muito. Não tem como vc se esquecer de lidar com a exceção.

Agora, lidar e resolver são coisas diferentes. O caller pode não saber resolver o problema. Nesse caso ele passará a exceção adiante. Mas agora ele é livre de dar tratamento À exceção. Por exemplo, encapsulando-a numa exceção não-verificada.

As API SQL , IO , Threads e Reflection não são mal projetadas. Isso é um mito levantado e alimentado por quem não sabe trabalhar com exceções. Elas usam exceções verificadas porque são API que ao serem chamadas o programador perde o controlo do que acontece ( aka, são chamadas “nativas” ).

As exceções do Hibernate ou do EJB poderiam não ser verificadas. Ai éuma decisão de design, mas não podemos censurar a escolha de usar exceções verificadas só porque temos preguiça de lidar com elas.

Na realidade , porque a maioria dos programadores não divide o programa em camadas , têm que lidar com exceções veirifcadas em todo o lugar da aplicação ( tipo tratar um SQLException dentro de um component siwing). Esse é que é o problema e não as exceções serem verificadas. Se encapsular o uso de SQL em uma camada, de arquivos em uma camada , de reflectino ,etc… nunca mais vai ter problemas com exceções verificadas.

As exceções verificadas são essenciais para um bom design da aplicação, especialmente se ela for um API de uso genérico.
Sem elas é possivel utilizar as mesmas funções da API mas com uma garantia a menos.

Na época em que querem criar anotações @NotNull para verificação automática da passagem de nulos não autorizados, não faz sentido apoiar a ideia de que exceções verificadas são inuteis. Quando mais facilidades existirem para construir bons designs de forma elegante, melhor.

Não digam que a API de SQL foi mal projetada porque usa exceções verificadas que isso pega mal. Ela foi mal projetada sim, mas em outros pontos. Por exemplo, falta de hierarquia de exceções mais fina (embora isso esteja sendo solucionado).

Emerson_Macedo

Se você tiver testes automatizados (e.g. unitarios, integrados e funcionais), certamente não se esquecerá de tratar quando for necessário.

Seguindo isso que você disse, poderíamos tirar todas as verificações de corretude que o compilador faz e deixar tudo isso ao cargo do programador e de seus testes unitários/funcionais/whatever.
Isso não tem nada ver com que eu disse, apesar de poder ser aplicado em alguns casos como na utilização de linguagens de tipagem dinâmica (neste caso o compilador não verifica os tipos). Mas voltando o que eu havia dito, se você fizer bons testes automatizados, provavelmente você vai testar os fluxos que você espera em cada caso.

Depende… ter testes não garante que o teste faz a validação adequada.
Concordo que de forma alguma checked exceptions substituem ou diminuem a importância de testes, mas elas pelo menos dão um feedback mais rápido.
Ter bons testes e uma boa cobertura destes te dá uma boa garantia. Quanto ao feedback mais rápido é questionável. Eu acredito que usando uma abordagem TDD meu feedback vem mais rápido através dos testes.

ramilani12

Então como vcs tratariam IOException? querendo ou não estamos sujeitos a erros inesperados o mesmo se aplica ao SQLException.
Semana passada tive um erro bem chato, o desenvolvedor definiu o limite da sequence em 999 e os campos que sâo alimentados pela sequence numeric(3) chegou um belo dia que chegamos no numero magico 1000 e desenvolvedor não tratou esta situação e o incrivel que driver da oracle tbm não tratava essa situação não lançava um “ORA:0XXX”.

Se tivesse tratado pelo menos com um SQLException a exceção seria mais obvia não igual a esta abaixo:
Erro da sequence

Erro do sistema: null
com.a.AException
	at com.a.ejbBase.ejbStoreBase(ejbBase.java:331)
	at applications.avaliacaoPd.Projeto.ejbStore(Projeto.java:282)
	at applications.avaliacaoPd.admin.AvaliacaoAdmin.doGet(AvaliacaoAdmin.java:190)
	at applications.avaliacaoPd.admin.AvaliacaoAdmin.doPost(AvaliacaoAdmin.java:39)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
	at com.a.ServletBase.service(ServletBase.java:78)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
	at org.apache.tomcat.core.ServletWrapper.doService(ServletWrapper.java:404)
	at org.apache.tomcat.core.Handler.service(Handler.java:286)
	at org.apache.tomcat.core.ServletWrapper.service(ServletWrapper.java:372)
	at org.apache.tomcat.core.ContextManager.internalService(ContextManager.java:797)
	at org.apache.tomcat.core.ContextManager.service(ContextManager.java:743)
	at org.apache.tomcat.service.connector.Ajp12ConnectionHandler.processConnection(Ajp12ConnectionHandler.java:166)
	at org.apache.tomcat.service.TcpWorkerThread.runIt(PoolTcpEndpoint.java:416)
	at org.apache.tomcat.util.ThreadPool$ControlRunnable.run(ThreadPool.java:498)
	at java.lang.Thread.run(Thread.java:534)

Tbm concordo com opinião do Victor, acho que as exceções checked são utilizadas de forma errada.

Emerson_Macedo

ramilani12:
Então como vcs tratariam IOException? querendo ou não estamos sujeitos a erros inesperados o mesmo se aplica ao SQLException.
Semana passada tive um erro bem chato, o desenvolvedor definiu o limite da sequence em 999 e os campos que sâo alimentados pela sequence numeric(3) chegou um belo dia que chegamos no numero magico 1000 e desenvolvedor não tratou esta situação e o incrivel que driver da oracle tbm não tratava essa situação não lançava um “ORA:0XXX”.

Tbm concordo com opinião do Victor, acho que as exceções checked são utilizadas de forma errada.


Partindo desse princípio que você disse, todas as exceptions deveriam ser checked pra não haver erros inesperados …
No mínimo seu sistema deve ter um tratador na última camada antes da apresentação que logue esse erro e apresente uma mensagem amigável para o usuário. A partir do conhecimento desse “novo erro inesperado”, você pode avaliar se precisa alterar seu sistema para trata-lo de alguma forma ou se esse tipo de erro não será possível ser tratado e o melhor a fazer mesmo é o descrito anteriormente.

ramilani12

Ermerson mas se tratando de IOException e SQLException

Emerson_Macedo

Sim, essas são as piores IMO. Não tem nem como se recuperar. Muito melhor é ter um tratamento genérico, logar e apresentar uma mensagem bem nice pro usuário. Não entendi muito bem a sua dúvida. Qual seria o ponto?

B

Então entramos num acordo aqui.

Clareando as idéias:

O cliente, para o bem dele, deve tratar exceções que o objeto a quem ele chamou lança.

A questão é se ele deve ser obrigado a fazer isto ou não, onde a obrigação se traduz para checked exceptions, a desobrigação para unchecked exceptions.

Pois bem, então é tudo questão de design?

Eu acho que o objeto chamado deve ter um modo de avisar (leia-se: warnings) quem o chama que este deve lidar com suas exceções, porém que este não deva ser obrigado a fazer isso, como Java o faz hoje.

Digamos que checked exceptions não precisem mais de blocos de try-catch, mas sim que o compilador gere diversos warnings, avisando que os métodos chamados devem ser tratados. É uma boa solução? unchecked exceptions continuariam como estão hoje, sem avisar ninguém. throws passariam os warnings p/ cima.

Emerson_Macedo

É uma ideia interessante. Hoje em dia se soluciona isso facilmente quando quem criou a classe que lança a exception documenta no javadoc as exceptions que podem ser lançadas em cada caso. Dessa forma, mesmo sendo unchecked, o cliente da classe vai saber o que precisa tratar.

danielbussade

Então entramos num acordo aqui.

Clareando as idéias:

O cliente, para o bem dele, deve tratar exceções que o objeto a quem ele chamou lança.

A questão é se ele deve ser obrigado a fazer isto ou não, onde a obrigação se traduz para checked exceptions, a desobrigação para unchecked exceptions.

Pois bem, então é tudo questão de design?

Eu acho que o objeto chamado deve ter um modo de avisar (leia-se: warnings) quem o chama que este deve lidar com suas exceções, porém que este não deva ser obrigado a fazer isso, como Java o faz hoje.

Digamos que checked exceptions não precisem mais de blocos de try-catch, mas sim que o compilador gere diversos warnings, avisando que os métodos chamados devem ser tratados. É uma boa solução? unchecked exceptions continuariam como estão hoje, sem avisar ninguém. throws passariam os warnings p/ cima.

Colaborando com o assunto; achei a sua idéia muito interessante, pois tira a obrigação de
usar try-catch todas as vezes deixando opcional, mas avisando dos riscos que este usuario corre.O que vejo ocorrer geralmente e que as pessoas se cansam de tratar as checked exceptions e acabam no final fazendo isso:

try {
			
		} catch (Exception e) {
			
		}

O que faz o mecanismo de exceções perderem todo o sentido!

Mas na outro lado da história, existem casos onde as checked exceptions são bem empregadas,como já citaram acima nas famosas IOException. Um exemplo é a FileNotFoundException, essa exceção deve ser checked pois o programador tem que ser obrigado a fornecer um tratamento caso um arquivo não seja encontrado, pois do contrário correrá o risco de jogar o stacktrace na “cara” do usuário.

No geral, são poucos casos onde o uso de checked exceptions são bem empregadas.

sergiotaborda

Os casos são poucos devido à falta de qualidade do design das aplicações.
Os desenvolvedores não pensam nesse problema o suficiente e quando pensam não o resolvem adequadamente.
A falta de seguimento das diretrizes de programação (aka boas práticas) e muitas vezes a falta de disciplina do programador ou da equipe levam o códigos como o do seu exemplo.

Se o tratamento de exceção está virando um problema é porque - provavelmente - não está sendo bem feito.
Não é natural que codigo de try-catch esteja espalhado pela aplicação toda.
Por outro lado, também não é natural que código que se repete ( o codigo no catch se repete bastante) não seja encaspulado em um método.

O padrão ExceptionHandlerajuda a resolver o problema. É especialmente util na presença de IOException e SQLException e pode converter qualquer exceção para uma não-verificada tipada : coisa que, tb, normalmente, o desenvolvedor não faz.

Trabalhar com exceções não-verificadas é muito mais simples, mas para que dê certo é preciso que elas sejam fortemente tipadas.
Ou seja, uma FileNotFoundException não pode virar uma RuntimeException. Tem que virar uma RuntimeFileNotFoundException filhe da RuntimeException.

Se seguirmos as boas práticas para lidar com exceções os problemas vão embora e podemos começar a apreciar a beleza e o visionarismo que existe nas exceções verificadas.

Mauricio_Linhares

Bruno Laturner:
Lendo o Mundo Java 33, sobre EJBs e Spring, na parte de controle de transações, fala que ambas as tecnologias fazem rollback da transação quando encontram unchecked exceptions, mas com as checked deixam rolar, supõem que o desenvolvedor queria que isso aconteça.

Fiquei pensando no caso de uma exceção na camada de persistência, como uma SQL ou IOException, normalmente não são esperadas pela aplicação.

A camada deveria tratar esses erros e transformá-los em erros do sistema quando a requisição voltar para a camada que a chamou? Acho meio infeliz dar um catch e um throw logo depois só pra transformar a exceção. O que tem de “checado” numa exceção dessas?

Só um adendo meio atrasado, tanto o Spring como o JPA vão empacotar automaticamente todas as IO e SQL exceptions que surjam no seu código, então eles não vão lançar checked exceptions, quem lança é o seu próprio código, por isso que as ferramentas não lidam com isso.

B

Pergunta rápida (ou nem tanto):

Exceções” da aplicação, por exemplo, caso você for procurar por uma pessoa pelo CPF, não encontrá-la e querer mostrar uma mensagem de “erro” ‘Pessoa não encontrada’ na tela.

Pensemos que é normal você não encontrar alguém, portanto não seria uma exceção, mas como vocês normalmente fazem para jogar essa mensagem lá dos confins interiores do sistema para uma JSP?

Pergunto por que uma solução que conheço é levantar um RuntimeException e deixar ele ir até a servlet, onde tem um código que vai fazer o logging e redirecionar p/ uma página de erro genérica com uma mensagem. O chato é ele ficar gerando log por coisas que não são exceções.

Tem uma solução mais elegante e ainda prática?

Emerson_Macedo

Se é normal você não encontrar alguém, não acho que seja bom lançar uma exception. Acho que o melhor é você retornar algo que indique que a pesquisa não retornou nada.

Em Java, pode retornar null, mas tem que tomar cuidado com NPE. Nesse caso, você vai ter que verificar se a referência é null e exibir a mensagem conforme necessário (você pode usar NullObject também se for o caso). Quando a pesquisa retorna uma lista a boa pratica é retornar a lista vazia ao invés de null.

B

Não, retornar nulos e checar por NPEs já faço, a questão mesmo é sobre usar exceções para exibir mensagens do programa numa página. Pergunto se isso é normal.

Mauricio_Linhares

Não, isso não é normal. Exceções devem ser utilizadas apenas se você realmente está em um caso que não é normal. Mostrar mensagens de erro pro usuário é uma coisa corriqueira que toda a aplicação tem, isso não deve ser feito com exceções.

Emerson_Macedo

Não, isso não é normal. Exceções devem ser utilizadas apenas se você realmente está em um caso que não é normal. Mostrar mensagens de erro pro usuário é uma coisa corriqueira que toda a aplicação tem, isso não deve ser feito com exceções.
++

B

Não, isso não é normal. Exceções devem ser utilizadas apenas se você realmente está em um caso que não é normal. Mostrar mensagens de erro pro usuário é uma coisa corriqueira que toda a aplicação tem, isso não deve ser feito com exceções.

É que estou pensando no caso em que o negócio quer mandar uma mensagem para o usuário. Parece que as únicas mensagens que ele pode enviar, fora o retorno, são as exceções. Já que exceções não fazem parte do fluxo normal, neste caso a própria view deveria verificar o retorno e imprimir uma mensagem de acordo.

Emerson_Macedo

Acho que o conceito ta um pouco confuso. O négocio não manda mensagem para usuario. Quem manda mensagem para o usuário é o componente View. Eu acho que o negócio deva retornar objetos de negocios ou exceções em casos anormais.

victorwss

<c:catch> ... </c:catch>

Emerson_Macedo

Tem uma discussão legal que rolou sobre esse assunto no stackoverflow relacionada a esse assunto que eu andei dando uma lida e é bem legal. Inclusive fala sobre recursos de oturas linguagens para resolver algumas das situações.

Lavieri

Sou de arocdo com o artigo que o Brunno postou logo no inicio, do Sergio Taborda, e tente me adequar… ainda não aprendi perfeitamente o padrão handle… mais estou sempre criando as exceções por camadas, e deixando exceções verificadas nos limites da camada, ou seja, qualquer método que possa lançar exceções e que é chamado de fora da camada lança exceções verificadas a camada de cima… e quem kizer q a trate na camada acima ^^

Lavieri

sem quere desenterrar muito o tópico ... mais la vai..

estou tentando seguir o que o sergio falou nos artigos dele... ser especifico, e não deixar para os outros tratarem os problemas q eu sei tratar...

sendo assim... estou fazendo tratamento bem legal das minhas exceções, criando Classes para auxiliar, o uso, e sempre que possivel, usando recursos já existente da propria API e otimizando esses recurso... abaixo vou mostar um exemplo do que estou fazendo...

Minhas entidadees recebem muitos argumentos, e estes argumentos devem seguir algumas regras, onde alguns podem ser nulos, outros não, alguns não podem exceder um comprimento tal, ou tem que ter um comprimento etnre X e Y ... entre varias outras situações... para poder tratar na propria classe, e mesmo assim conseguir ser muito especifico no erro, e poder tratar do ERRO em uma camada la em cima depois, eu fiz o seguinte...

IllegalArgumentException
    |
    |-DetailedIllegalArgumentException //Aqui eu consigo guardar, Source,PropertyName,Argument
        |
        |-IllegalSizeException //Além dos dados anterior, guardo tb o Tamanho esperado, e o tamanho checado.
        |   |
        |   |-MaxMinSizeException //Apenas uma exceção generica pra usar no cautch, quando abrange as 2 de baixo.
        |       |
        |       |-MaximumSizeException //Guarda o valor maximo permitido e o valor encontrado
        |       |
        |       |-MinimumSizeException //Guarda o valor minimo permitido e o valor encontrado
        |
        |-IllegalNullArgumentException //Especifica que um argumento que não podia ser null foi passado como null

Explicando as classes e colocando os links
DetailedIllegalArgumentException - Esta classe alem do tradicional de IllegalArgumentException é capaz de armezanar tb informações como:
- Source: o objeto fonte (source) que esperava o argumento enviado, e que o constatou q este era invalido.
- Property Name: o nome da propriedade do objeto fonte, que iria receber o argumento passado.
- Argument: a referencia do objeto que foi passado como argumento e que foi dado como ilegal.

IllegalSizeException - Além do já citado antes, é capaz de guardar ainda o valor esperado, e especifica que o problema no argumento é relativo ao seu comprimento, além de informar tb o comprimento constatado no momento que a exceção foi gerada.

MaxMinSizeException - Indica que o problema foi pq o argumento passado tinha comprimento fora dos valores Maximo permitido ou Minimo permitido.

MaximumSizeException - Indica que é uma exceção de maximo.
MinimumSizeException - Indica que é uma exceção de minimo.

IllegalNullArgumentException - Indica que o argumento passado não podia ser nulo, alem de informar o restante de DetailedIllegalArgumentException.

.......

Desta forma eu programo meus beans de forma bem mais coerente, e com a certeza que na camada superior vou conseguir recuperar todas as informações relevantes caso uma exceção seja lançada, sem precisar debugar o problema...

por exemplo um bean pessoa

public class Pessoa {
    private String nome;
    private String cpf;
    private String email;
//...
    public void setNome(String nome) {
        if (nome == null)
            throw new IllegalNullArgumentException(this,"nome",nome);
        if (nome.length() > 45)
            throw new MaximumSizeException(this,"nome",nome,45,nome.length());
        this.nome = nome;
    }
// o mesmo faço para cpf, email etc etc...
}

por exemplo... digamos que eu tenha um constrole que pegue os dados de 1 interface, passar para um bean e envie para cadastramento... ao coletar os dados da interface e passar para o bean, o bean vai automaticamente lançar as exceções, sem eu, neste momento ter q me preucupar muito com API do bean, basta verificar as throws que o set lança... digamos que meu bean Pessoa, com os dados do CPF, nome, e-mail sejam passados...

public Pessoa cadastraPessoa(String nome,String cpf,String email) {
     Pessoa pessoa = new Pessoa();
     pessoa.setNome(nome);
     pessoa.setCpf(cpf);
     pessoa.setEmail(email);
     Repositories.save(pessoa);
     return pessoa;
}

agora fazendo

try {
     Pessoa pessoaCadastrada = cadastraPessoa(nome,cpf,email);
catch(MaximumSizeException ex) {
      //aqui eu consigo obter qualquer informação, como:

      //nome da propriedade.
      System.out.println(ex.getPropertyName());

      //valor do argumento passado.
      System.out.println(ex.getArgumento());

      //valor maximo do comprimento permitido.
      System.out.println(ex.getLimit());

      //a entidade onde a exceção foi gerada
      System.out.println(ex.getSource());
      
      //o tamanho do comprimento encontrado
      System.out.println(ex.getSize());
}

assim acredito que estou fazendo ficar bem facil e dinamico meu código e melhorando o tratamento de exceções...

Ps.: tenho uma classe chamda Consistencies, para fazer os testes pra mim, pra não ficar poluindo de + os bens com os testes de consistencia, assim ficaria algo assim
Consistencies.sizeMax(this,"nome",nome,45); //fonte = this, nome da propriedade = "nome"; valor do argumento = nome, tamanho maximo permitido = 45

Ps.2: esse é uma pequena parte das minha exceções, apenas para exemplificar

Emerson_Macedo

E você pode me dizer onde que você está se recuperando do erro? Usar exceptions verificados e ainda por cima simplesmente para logar o erro não me parece uma boa estratégia por tudo que já foi debatido neste tópico.

Lavieri

E você pode me dizer onde que você está se recuperando do erro? Usar exceptions verificados e ainda por cima simplesmente para logar o erro não me parece uma boa estratégia por tudo que já foi debatido neste tópico.

Quem falou em usar exceptions verificadas só para logar erro ?? …

A questão ate onde entendo é que vc deve no limite da camada, mostrar para quem vá usa-la que ela lança exceções, e que o usuario deve estar ciente destas exceções, e trata-los como achar conviniente… caso não seja capaz de tratar, basta avisar com um throws, ou usando o padrão handle, convertendo a exceção gerada na camada de baixo, em uma desta camada, de forma que a proxima camada de cima, não precise conhecer a que esta abaixo desta…

Por exemplo, o meu start do banco, que cria o SessionFactory do Hibernate é um método que lança exceção verificada, isso se justifica, pois existe N possiveis casos onde isso pode gerar exceções, o banco pode não estar instalado na maquina, pode não haver conexão com a internet ou intranet para conectar com o banco, pode ocorrer N coisas, portanto tenho um exceção verificada nesse ponto… assim eu monto minha session factory explicitamente, através de uma chamada, que lança exceções… faço verificado nesse ponto, por acreditar que mesmo fazendo tudo certo dentro do programa, um fator totalmente externo (como uma desconexão com a internet) pode ocasionar em problemas aqui…

Os repositorios por sua vez, que utilizam a conexão do hibernate e o sessionfactory, caso a sessionFactory não esteja presente, eu não lanço exceções verificadas, pois acho q isso poluiria de verdade o código, faço um tratamento e lanço Runtimes, acredito que a conexão que foi feita de modo explicito anteriormente e com a exceção verificada, vai fazer um correto tratamento, posteriormente lembranco apenas que a exceção pode surgir, mais q não precisa ser verificada…

Eu tento tomar bastante cuidado, ao lançar as exceções verificadas, acredito que o melhor momento pra faze-lo é quando mesmo que vc esteja fazendo tudo direito, mesmo assim algo pode dar errado, por motivos externos, Um banco de dados desligado, um arquivo que deveria estar em um lugar e não esta… etc etc etc…

No exemplo do post acima, modelando uma entidade, não faço verificado, pois acredito que o erro seja realmente RunTime, não ha motivos de obrigar a fazer um try{}catch(){} em um set da entidade, o parametro estar dentro das especificações é algo q eu posso controlar antes de mandar o valor para entidade, portanto posso ter 100% de garantia que o valor q mando pra entidade é conforme…

já na hora de salvar uma entidade, por exemplo, não tenho como ter 100% de certeza que consigo salvar a entidade, não tenho como ter 100% de certeza que não vou esbarrar num CONSTRAINT de algum campo UNIQUE por exemplo, e nessa hora, mesmo eu fazendo tudo certo algo pode dar errado… por isso… Repositories.save(entity); gera exceções verificadas… assim acredito estar fazendo certo…

com findAll(), findById(id), findByNome()…, deletes(), por exemplo, não faço verificado, pois se eu garantir que os dados que estou mandando estão corretamente, o erro so vem, se a conexão com o banco estiver ausente, o que trato la no inicio, na hora de start o programa…

enfim… assim tenho exceções verificadas, e não verificadas…

Edit.: Não acho correto por exemplo, ao fazer um Repositories.save(clienteJoao); receber uma SQLException, apenas com uma mensagem “Constraint Violation Unique Key bla bla bla…” … como programando la no controle entre a view e o modelo, vou conseguir tratar um erro desse ??, tenho que dentro do repositorio conseguir entender o que é esse erro que o hibernate gera, que é gerado por conta de um erro do SQL, e tenho que tratalo, devo mastigar o erro, posi ali que estou programado com a camada de persistencia, ali eu tenho que fazer isso virar legivel, de forma que daqui, saia algo como ConstraintViolationException que contenhas informações como, a referencia a entidade que continha o valor que gerou a exceção (a partir dela da pra pegar o nome da entidade, ou ate mesmo recuperar os dados da entidade, mostrar de volta par a view, e pedir que seja alterado o compo onde há a violação), valor que não foi permitido (se possivel com o nome da propriedade, assim podendo especificar para a view o que o meu usuario deve mudar, para poder salvar o registro), o valor que era esperado, e outras coisas, que seja util, e de facil interpretação para que o controle, através de um try{}catch(){} obrigatoriamente verificado, possa tratar, e repassar o erro para a view, com algo elegante como:

Verificamos que o CPF : [CPF removido] já existe em nosso banco, cadastrado para o senhor “Fulano de tal”, assim não foi possível cadastrar o Senhor “Beltrano da Silva” sobre o mesmo número de CPF, o que deseja fazer ? carregar os dados de “Beltrano da silva”? Salvar as novas informações digitadas para “Fulano de tal” por cima dos dados de “Beltrano da silva” ?

enfim essas coisas eu posso verificar, no momento da exceção, por gerar uma Exception rica em informação, para melhroar o tratamento

Emerson_Macedo

E você pode me dizer onde que você está se recuperando do erro? Usar exceptions verificados e ainda por cima simplesmente para logar o erro não me parece uma boa estratégia por tudo que já foi debatido neste tópico.

Quem falou em usar exceptions verificadas só para logar erro ?? …
O seu exemplo não fez nada alem de um sysout.

Para ele estar ciente basta você documentar no javadoc as invariantes do seu objeto, pré condições das operações e exceptions lançadas. Além disso, ter testes automatizados na sua API para que ele possa saber como usa-la corretamente.

E o que o cliente do seu objeto poderia fazer com essa exception alem de lança-la para uma camada acima? Daria para se recuperar? Percebe que não faz sentido essas checked exceptions?

Lavieri:
Eu tento tomar bastante cuidado, ao lançar as exceções verificadas, acredito que o melhor momento pra faze-lo é quando mesmo que vc esteja fazendo tudo direito, mesmo assim algo pode dar errado, por motivos externos, Um banco de dados desligado, um arquivo que deveria estar em um lugar e não esta… etc etc etc…

já na hora de salvar uma entidade, por exemplo, não tenho como ter 100% de certeza que consigo salvar a entidade, não tenho como ter 100% de certeza que não vou esbarrar num CONSTRAINT de algum campo UNIQUE por exemplo, e nessa hora, mesmo eu fazendo tudo certo algo pode dar errado… por isso… Repositories.save(entity); gera exceções verificadas… assim acredito estar fazendo certo…


Como eu disse acima, nesses casos, não existe como se recuperar do problema, não faz o menor sentido usar checked exceptions. E mesmo que fizesse, na resposta acima eu mostro como tornar a vida do cliente do seu objeto menos burocratica.

Dá uma relida com calma em toda essa thread desde a primeira página que tem várias dicas pra entender o que eu coloquei aqui.

[]s

Lavieri

A questão de se recuperar ou não do problema é algo parcial… em algum momento, a não ser que eu queira que o meu usuario veja um despejo de StackTrace eu vou ter que usar o Try-Cacth… sendo assim, ao conectar com o banco, gerando tal problema, eu devo tratar, e tomar alguma atitude.

Dizer que a exceção é checked, para mim é util, quando vc deve avisar para o cliente do seu objeto, que mesmo que ele faça tudo certo, mesmo assim, algo pode dar errado, e que ele arrume tratamento para isso, ou seja, que ele tenha o plano B, pois isso não depende do meu objeto, nem dele me passar todos os argumentos corretamente… por isso o que vai fazer é TENTAR(try) usar o meu objeto, ele nem eu tem como garantir que dará certo

As exceções não verificadas indicam ao cliente do meu objeto, que se ele não mandar todos os argumentos corretamente, neste caso uma exceção será lançada, esta exceção, só vai depender dele, e ele tem como resolver todos os problemas antes do argumento chegar a meu objeto de forma ilegal, sendo assim, ele não precisa usar TRY, ou seja, ele não precisa tentar usar o meu objeto, pois se os argumentos estão corretos o uso funcionará…

For isso, acredito que quando vc esta programando algo generico, fazendo utils, por exemplo, que serve a varios pontos do programa, essa sua “API” que vc ta montando, gera algumas exceções, que estes exceções devem ser bem documentados, e sempre que preciso (se baseando principalmente nos 2 pontos falado anteriormente) deve ser feito a exceção verificada sim…

Ps.: eu li a thread toda, só não concordo que exceções chekeds são inuteis, e que devem ser abolidas… assim como acredito como falei no outro post, ainda nesta mesma pagina, que as exceções devem ser tratadas sempre por quem mais entenda do assunto, e devem ser lançadas sempre com o maximo de detalhes possiveis, para que a pessoa que vá fazer o tratamento, possa saber como o problema ocorreu, sem necesssidades de debugs e etcs

Emerson_Macedo

Para isso se faz um tratamento genérico nas aplicações web onde existe uma páginas de erro com mensagens amigaveis. É bem simples de fazer e todos os frameworks atuais dão suporte a isso.

Como eu disse acima e em toda thread você obtem o mesmo resultado com exceções uncheked só que dá a liberdade para o seu cliente escolher ao invés de impor que ele faça um try-catch. Se ele achar por bem fazer alguma coisa ele ainda sim tem essa opção de fazer o try-catch.

Isso gera sim uma burocracia bem chata.

Curioso é que Java é uma das unicas se não a única linguagem que tem checked exceptions. Como será que os programadores das outras linguagens conseguem trabalhar sem esse recurso? Já dei uma dica nas citações acima. Seria java mais esperta que as demais?

Da uma lida no que Bruce eckel disse sobre o assunto a alguns anos atrás: http://www.mindview.net/Etc/Discussions/CheckedExceptions

sergiotaborda

Lavieri:

public class Pessoa { private String nome; private String cpf; private String email; //... public void setNome(String nome) { if (nome == null) throw new IllegalNullArgumentException(this,"nome",nome); if (nome.length() > 45) throw new MaximumSizeException(this,"nome",nome,45,nome.length()); this.nome = nome; } // o mesmo faço para cpf, email etc etc... }

Ps.2: esse é uma pequena parte das minha exceções, apenas para exemplificar

Muito bem. É isso mesmo.
Apenas para o ajudar mais recomendo que implemente uma classe utilitária de consistencia.
Assim em vez de ifs vc faria

public void setNome(String nome) {
        Consist.notNull(nome); // lança new IllegalNullArgumentException
        Consist.maxLength(nome, 45); // lança new MaximumSizeException

        this.nome = nome;
    }

Avalie se o argumento this realmente é importante para os seus exceptions ( não deveria ser porque ele já consta do stacktrace)

Lavieri

sergiotaborda:
Lavieri:

public class Pessoa { private String nome; private String cpf; private String email; //... public void setNome(String nome) { if (nome == null) throw new IllegalNullArgumentException(this,"nome",nome); if (nome.length() > 45) throw new MaximumSizeException(this,"nome",nome,45,nome.length()); this.nome = nome; } // o mesmo faço para cpf, email etc etc... }

Ps.2: esse é uma pequena parte das minha exceções, apenas para exemplificar

Muito bem. É isso mesmo.
Apenas para o ajudar mais recomendo que implemente uma classe utilitária de consistencia.
Assim em vez de ifs vc faria

public void setNome(String nome) {
        Consist.notNull(nome); // lança new IllegalNullArgumentException
        Consist.maxLength(nome, 45); // lança new MaximumSizeException

        this.nome = nome;
    }

Avalie se o argumento this realmente é importante para os seus exceptions ( não deveria ser porque ele já consta do stacktrace)

Lavieri:

Ps.: tenho uma classe chamda Consistencies, para fazer os testes pra mim, pra não ficar poluindo de + os bens com os testes de consistencia, assim ficaria algo assim

Ps.2: esse é uma pequena parte das minha exceções, apenas para exemplificar

Eu ja tinha ate falado no outro post que fazia por meio do Consistencies, só não coloquei direto no exemplo, pra ficar mais facil o exemplo…
Consistencies.java ai ta só uma parte do .java … ele é muito grande heheh, ai nem postei la o código todo…

Sergio… eu uso o “this” justamente pq a exceção quase nunca é lançada do proprio objeto, ela sempre passa pelmenos pelo “Consistenties” assim fica melhor de fazer a referencia ao objeto onde a exceção ocorreu, se tiver uma ideia melhor… gostaria q fosse facil de pegar o objeto… com apenas… ex.getSource()

sergiotaborda

Lavieri:

Sergio… eu uso o “this” justamente pq a exceção quase nunca é lançada do proprio objeto, ela sempre passa pelmenos pelo “Consistenties” assim fica melhor de fazer a referencia ao objeto onde a exceção ocorreu, se tiver uma ideia melhor… gostaria q fosse facil de pegar o objeto… com apenas… ex.getSource()

Você pode utilizar o truque de determinar quem lançou a exceção, para isso basta analisar o stacktrace da exceção.

Criado 28 de janeiro de 2009
Ultima resposta 10 de mai. de 2009
Respostas 55
Participantes 14