Sempe que algum método x é executado dentro de um método y, esse método y deve ter um um throws na declaração, caso o método x pode gerar uma exceção? Dessa forma, uma exceção sempre deve ser tratada com o catch ou o método deve passar a exceção para um outro método tratar. Seria isso?
Normalmente eu faço apenas.
public void metodo (){
try{
metodo_dois();
}catch(Exception e){
System.out.println(e.getMessage);
}
}
Voce deve usar o throws nos metodos para tratar exeções que possam ser gerados pelos metodos, como vc saberia qual o erro gerado se voce tentasse se conectar a uma classe de conexao de banco de dados ?
imagino que sempre que voce usar um bloco try / catch é indispensável o uso do throws !! Nao sei se esclareu sua duvida.
falo
Exato para checked exceptions, unchecked exceptions (exceções que descendem de RuntimeException) não precisam de throws (i.e. NullPointerException)
[quote]Voce deve usar o throws nos metodos para tratar exeções que possam ser gerados pelos metodos, como vc saberia qual o erro gerado se voce tentasse se conectar a uma classe de conexao de banco de dados ?
imagino que sempre que voce usar um bloco try / catch é indispensável o uso do throws !! Nao sei se esclareu sua duvida.[/quote]
Hehehe,
eu até pensei que tinha entendido. Agora com essa resposta, vi que não entendi.
Bom… no try…catch, não seria melhor criar um Dialog e mostrar uma mensagem para o usuário informando o erro?
Veja esse método:
[code] public void addMaterial(DescricaoMaterial novoMaterial, BigDecimal quantidade){
// pré-condição
if ( (quantidade.compareTo(new BigDecimal(0)) <= 0) ) throw new IllegalArgumentException();
…
} [/code]
Eu teria que acrescentar o throws na declaração do método também?
Sim, deveria explicitar na declaração do método.
Ou colocar este if dentro de um bloco try/catch e tratá-lo no catch.
É um tanto simples, você tem duas alternativas, ou trata a exceção dentro do seu catch, ou re-lança a exceção(e quando fizer isso deve estar explícito no método).
Ok, entendi esse esquema já. Ou trata ou deixa a exceção para ser tratada por outro método, colocando uma cláusula throws na declaração do método.
Mas no código fonte que citei acima, não é necessário incluir o throws na declaração do método, certo?
[quote=Rafael Nunes]Sim, deveria explicitar na declaração do método.
Ou colocar este if dentro de um bloco try/catch e tratá-lo no catch.
É um tanto simples, você tem duas alternativas, ou trata a exceção dentro do seu catch, ou re-lança a exceção(e quando fizer isso deve estar explícito no método).[/quote]
No metodo VisualizaRelatorio, eu estou tratando as exceções. No entanto, estou tb relançando. Nesse caso, ao chamar esse metodo de uma outra classe eu terei que tratar novamente as exceçoes ??
final public class Teste
{
private JInternalFrame viewer = null;
public void VisualizaRelatorio(final String pathRelatorio, final String nomeRelatorio, final
String sql, final String titulo, final ParametroRelatorio obj)
{
InputStream is = null;
try
{
Map<String, ParametroRelatorio> parameters = new HashMap<String, ParametroRelatorio>();
parameters.put("obj", obj);
JRResultSetDataSource jr;
if (nomeRelatorio.equals("EtiquetaRepetida.jasper"))
{
jr = new JRResultSetEtiquetaRepetidaDataSource(rs);
}
else
{
jr = new JRResultSetDataSource(rs);
}
JasperPrint print = JasperFillManager.fillReport(is, parameters, jr);
JRViewer jrv = new JRViewer(print);
viewer = new JInternalFrame(titulo, true, true, true, true);
viewer.setSize(750, 650);
viewer.getContentPane().add(jrv);
viewer.setMaximum(true);
viewer.setSelected(true);
viewer.setVisible(true);
}
catch (JRException jre)
{
throw new RuntimeException(jre);
}
catch (PropertyVetoException e)
{
throw new RuntimeException(e);
}
catch (SQLException e)
{
throw new RuntimeException("Erro ao executar consulta",e);
}
finally{
try {
is.close();
}
catch(IOException e){
throw new RuntimeException("Erro ao tentar fechar InputStream",e);
}
}
}
}
[edit]
Correção, fiz um teste aqui e IllegalArgumentException() você não é obrigado a tratar, creio que é uma exceção de Runtime, como o Phillip falou. Você só é obrigado a tratar exceções checadas. Por exemplo substitua IllegalArgumentException() por Exception() e você será obrigado a tratar no próprio método ou explicitar na declaração.
[quote=Javax]
No metodo VisualizaRelatorio, eu estou tratando as exceções. No entanto, estou tb relançando. Nesse caso, ao chamar esse metodo de uma outra classe eu terei que tratar novamente as exceçoes ?? [/quote]
[edit]Nope, você não é obrigado pois são Runtime Exceptions, e estas não são obrigatórias sua declaração ou tratamento
E para o tratamento de pré-condições, pós-condições…
O que seria mais adequado? Eu poderia continuar usando exceções não checadas ou deveria fazer as checadas?
No artigo sobre contratos nulos, eu vi o uso de exceções não checadas. Teria algum problema nisso, ou basta deixar bem documentado os métodos?
[code] public void addMaterial(DescricaoMaterial novoMaterial, BigDecimal quantidade){
// pré-condição
if ( (quantidade.compareTo(new BigDecimal(0)) <= 0) ) throw new IllegalArgumentException();
…
} [/code]
Isso depende muito do escopo do teu projeto em que momento essa exceção será lançada(ou o contrato será quebrado). Não tratar exceções pode ser perigoso, pois em um momento que ela for lançada(por exemplo em tempo de execução), se o usuário não tiver conhecimento do que está acontecendo, vai ser meio complicado encontrar qual o problema.
Imagine que esta quebra de contrato aconteça em tempo de execução, como você garantirá a pós-condição ou informará o usuário do que está acontecendo?
Realmente, acho que devemos sempre usar exceções checadas mesmo.
Lá no The Java Tutorial isso foi bastante recomendado.
Tudo depende.
Existe uma tendência (até onde eu sei) provocada pelo Rod Johnson no Spring de exceções unchecked para coisas que realmente nãod everiam acontecer em hipotese alguma.
Não conectar com o banco de dados, por exemplo, é algo anormal demais, isso não deve acontecer. Se você criar checked exceptions, vai ter um monte de código dedicado a cuidar de uma condição que não deve acontecer (a robustez da aplicação, estrutura e do seu application server deve ser suficiente para não deixar a JVM cair e exibir uma mensagem amigavel de erro, no entanto).
Se tratando de contratos, como rule of thumb eu uso unckecked para quebra de pré-condições (o cliente deveria saber não fazer besteira) e checked para pós-condição (eu tenho que me responsabilizar pela porcaria que faço). Não sei se esta é a melhor alternativa, na verdade acabei de me dar conta de que eu sempre uso esse padrão.
Quando você diz que utiliza unchecked, significa que você não as trata?
Por exemplo suponha que o seu cliente utilize um determinado objeto, lhe passando o que a interface pede:
[code]Objeto:
public void fazAlgo(int a, int b)
Cliente
fazAlgo(int,int);[/code]
Suponha que seu objeto possui uma invariante de que os inteiros recebidos devem estar em 1 e 50. E o cliente está recuperando estes inteiros de uma interface gráfica ou arquivo de configuração.
Isso significa que ele é quem deveria verificar a pré-condição para satisfazer a invariante?Ou você é quem verifica a pós-condição e lança a exceção?
[quote=Rafael Nunes]
Suponha que seu objeto possui uma invariante de que os inteiros recebidos devem estar em 1 e 50. E o cliente está recuperando estes inteiros de uma interface gráfica ou arquivo de configuração.
Isso significa que ele é quem deveria verificar a pré-condição para satisfazer a invariante?Ou você é quem verifica a pós-condição e lança a exceção?[/quote]
Quem garante a pré-condição é o cliente, sempre. Se ele leu de algum lugar, alguém contou pra ele, sei lá, ele tem que validar antes de passar pra frente.
Imagina
void doStuff(Object o){
System.out.println(o.toString());
}
public static void main(String[] a){
doStuff(null);
}
Quem tá errado na história?
Hun, entendi, grato.
E como você documenta/informa uma invariante do seu objeto?Um comentário no javadoc do método?
Eu tenho algumas pré-condições, que são simples.
Se altura <= 0 ou quantidade <= 0 gera a exceção.
Nesses casos, creio que teria que ser checked, não é?
Pelo que entendi no The Java Tutorial, isso seria o recomendado.
E se tiver fazendo um método private. Nesse caso não precisaria de fazer o tratamento de pré-condição? O que acham? Tenho uns casos desse jeito aqui e não estou vendo muita vantagem em lançar exceção, pois tem métodos que só são chamados em um local. Eu só deixei em um método separado para ficar mais organizado.
[quote=ronaldorezende]
Nesses casos, creio que teria que ser checked, não é?
Pelo que entendi no The Java Tutorial, isso seria o recomendado.[/quote]
Não: