Problemas com o entendimento de: Try / Catch / Throws / Throw

Pessoal… realmente nao consegui entender bem… faltou um bom exemplo na apostila… eu entendo melhor vendo o codigo do que com a parte teorica… alguem tem um codigo ai ja feito??

Em relacao Throws / Throw

qual a diferenca deles???
Oque significa “passar pra frente” -> expressao da apostila…

Try / Catch

eu vou ter que saber sempre o tipo de erro??

bem, eu ainda não estudei isso, mas sei que o Try é um bloco, em que você coloca o código que pode vir a dar erro,
ae quando da esse erro, ele vai tratar o evento no bloco catch, e no catch ele lança o erro e o throw faz uma nova ação caso tenha chegado nesse erro.

Olha, o tipo de erro ao meu ver é simples, teste muitas possibilidades, por exemplo, onde é pra digitar um double, separando com " . ", separe com " , "
e veja qual o erro que dá e trate-o.
Vá testando muitos erros que você acha que é capaz de ocorrer, veja qual o erro, pesquise como trata-lo, e trate-o.

tomara que algo ajude.
um abraço.

1 curtida

o bloco try-catch/try-catch-finally tem a função de fazer determinadas ações em que algum método possa vir a causar uma exception (não um erro… erros não são possíveis de se tratar no programa e geralmente são causados por problemas de hardware ou de compilação). É possível que existam vários catches para um único try, cada um fazendo um tratamento diferente para determinadas exceptions.
a dúvida no throw: em inglês, literalmente, catch é pegar e throw é arremessar. Ou seja, para que seja possível “pegar” uma exception dentro do try, alguém precisa vir a “arremessar” essa exception, e esse alguém é um método. Isso serve para quando existem diversas chamadas ao método em que o tratamento da exception é diferente, para quando você sabe que aquela exception pode acontecer (ou até mesmo gerar ela), mas não sabe o que fazer depois disso, então “passa para a frente” a responsabilidade de tratar a exception.

Exemplificando:

try { int[] teste = new int[5]; teste[10] = 10; // arremesso de exceção "fora do índice" } catch (Exception ex) { // tratamento do erro }
Claro que isso nunca vai acontecer, é um exemplo básico.
Agora um método que pede a posição do vetor e o novo valor:

[code]class … {
private int[] teste = new int[5];

public void alterarValor(int posicao, int valor) { // aqui existem dois casos: você tratar a exceção (como no caso anterior) ou arremesá-la de volta
// no caso de tratar a exceção aqui, caso a posição seja inválida, o tratamento será sempre idêntico, não importa onde o método for chamado
// mas podemos arremessar a exceção de volta para quem chamou tratá-la
}

public void alterarValor2(int posicao, int valor) {
try {
alterarValor(posicao, valor);
} catch (Exception ex) {
// aqui tratamos de um jeito a exceção gerada no alterarValor() e que foi arremessada… podemos ter outros infinitos métodos que chamem o alterarValor() e façam um tratamento diferente
}
}
}[/code]

desculpa qualquer erro e falta de codificação do throw, tô falando por lógica de outras linguagens, nunca fiz isso em Java

Seguinte… ao dizer que o throw “joga pra frente”, significa que quando a sua linha de código que contenha o throw seja executada (muitas vezes fica em um bloco catch) ela vai tiralmente “lançar” essa exception pro método anterior no stack (ou em outras palavras, pro código onde o método com throw foi chamado). Esse exemplo vai clarear as coisas provavelmente:

class Foo {
public void metodoException(){
try{
//tenta converter um input do usuario para inteiro
Integer.parseInt(JOptionPane.showInputDialog(null, "digite um número"));
} catch (Exception ex){
//caso o usuario tenha digitado um caractere inválido, uma exception será lançada
throw new Exception("número incorreto"); //Não quero tratar esse erro aqui, quero que o código que chame esse método se vire com isso
}
}
}

agora a classe que chama o método usa try-catch para tratar a exceção que pode ser jogada caso o exception seja lançado:

class Teste {
public static void main(String[] args){
try{
new Foo().metodoException();
} catch (Exception ex){
//trata a exceção que o metodoException pode lançar
System.out.println("FUUUU");
}
}
}

Agora, a diferença do throw pro throws é que, o throw voce especifica onde exatamente do código voce vai lançar sua exception, enquanto o throws é usado log na declaração do método:

class Foo {
public void metodoException() throws Exception{
//se, em algum momento, algum código dentro deste método der erro, o método lança uma Exception
Integer.parseInt(JOptionPane.showInputDialog(null, "digite um número"));
}
}
}

Não posso falar muita coisa teórica sobre o uso dele, e acho que nem vem ao caso você saber por enquanto, mas confesso que minha explicação ficou um lixo porque tou com pressa agora.

Bom o throw é quando você quer avisar ao contexto anterior da sua pilha de execução que algo saiu errado.
Por exemplo.

(...) // O throws aqui dfiz que esse método pode disparar essa excessão! public void sacar(Double quantidade) throws SaqueNegativoException{ if(quantidade < 0){ // Disparando a excessão daqui. throw new SaqueNegativoException(); } (...) }

Nesse caso o seu método sacar sabe que alguma coisa deu errado, mas quem vai ter que tratar isso é quem chamou esse método.
Estamos no modelo e essa classe não sabe para que ‘página’ redirecionar, como avisar isso pro usuário ( em que idioma?), nem mesmo se estamos numa aplicação Web ou Desktop, tudo que sabemos é que algo deu errado e que alguém tem que resolver.

E quem for chamar o método sacar Precisa saber tratar isso, ela tem que decidir o que fazer.

(...)
 
 try{
    conta.sacar(valor)
 }catch(SaqueNegativoException e){
    // A linguagem Java obriga você, quando chama o método sacar a tratar a exceção.
    redirecionarPaginaDeErro();
 }

Se a classe que usa o método ‘‘sacar’’ ela pode simnplesmente ‘passar pra frente’ novamente:

try{ conta.sacar(valor) }catch(SaqueNegativoException e){ rollback(); // Desfazendo alterações não finalizadas // Começando tudo denovo 'subindo' a excessão, não sabemos mais o que fazer aqui, passamos a bola pra quem talvez saiba. throw e; }

Espero ter ajudado, se não fui claro pergutae!
Abraço.

A instrução try serve para delimitar o bloco de código em que pode ser lançada uma exceção.
Escrever um bloco de código que deve ser executado caso ocorra a exceção, este bloco é delimitado através da instrução catch, e é denominado bloco de tratamento de exceção. Como a instrução catch recebe um tipo especifico de exceção como parâmetro, diz-se que ela captura uma exceção.

Se uma parte dentro do código try lança uma exceção da classe especifica, ou derivada da classe especificada na instrução catch, o programa para a execução do código na linha em que ocorreu o lançamento da execução e logo em seguida o programa executa o código de manipulação de exceções dentro do bloco de instrução catch e se o programa não lançar uma exceção dentro do bloco try, então o código dentro da instrução catch não será executado.

Para que a mensagem de erro da jvm não seja impressa, e para que apresente uma mensagem de erro adequada. veja um simples exemplo:

Package br.com.fexx.exceptions;

Public class Divisao{
	Public static void main(String [] args){
	Int a = 33;
	Int b = 0
	Try{
		Double res = a / b;
	System.out.println(a+" / "+b+" = "+res);
}catch (ArithmeticException e ){
	System.out.println("Divisao invalida");

}

}

} 

Leia:



segue o codigo… deixa eu ver se eu entendi rs

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

import java.util.Scanner;

public class ContaInterface {

public static void main(String[] args) {
    
    ContaCorrente c1 = new ContaCorrente();
    c1.deposita(500);
    Scanner input = new Scanner(System.in);
    try {
    c1.saca(Integer.parseInt(input.nextLine()));
    } catch (NumberFormatException x){
        System.out.println("Parametro Invalido");
    } catch (RuntimeException x){
        System.out.println(x.getMessage());
    }
    
    System.out.println(c1.getSaldo());

} }
[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

/**
*

  • @author Rafael
    */
    public interface Conta {

    double getSaldo();
    void deposita(double valor);
    void saca (double valor);

}
[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

/**
*

  • @author Rafael
    */
    public abstract class ContaAbstrata implements Conta {

    protected double saldo = this.limite+this.saldo;
    protected double limite = 200;

    @Override
    public double getSaldo() {
    return this.saldo;
    }

    @Override
    public void deposita(double valor) {
    this.saldo += valor;
    }

    @Override
    public void saca (double valor){
    this.saldo -= valor;
    }

}[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

/**
*

  • @author Rafael
    */
    public class ContaCorrente extends ContaAbstrata implements Conta {

    @Override
    public void saca(double valor) throws RuntimeException {

     if (valor < 0) {
         throw new RuntimeException("Valor Negativo");
     }
     if (valor > this.saldo) {
         throw new RuntimeException("Saldo Insuficiente");
     } else {
         this.saldo -= valor;
         System.out.println("Saque efetuado com sucesso");
     }
    

    }

    }[/code]

vê se eu fiz certinho ai rs

fiz o seguinte:

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

public class ContaInterface {

public static void main(String[] args) {
    
    ContaCorrente c1 = new ContaCorrente();
    c1.depositaThrow();
    c1.sacaThrow();
    
    System.out.println(c1.getSaldo());

} }
[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

/**
*

  • @author Rafael
    */
    public interface Conta {

    double getSaldo();
    void depositaThrow ();
    void sacaThrow ();

}
[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

import java.util.Scanner;

/**
*

  • @author Rafael
    */
    public abstract class ContaAbstrata implements Conta {

    protected double saldo = this.limite + this.saldo;
    protected double limite = 200;
    protected String num_cartao_deb;

    @Override
    public double getSaldo() {
    return this.saldo;
    }

    @Override
    public void depositaThrow() {
    System.out.println("Digite o valor que você quer depositar\n> ");
    Scanner input = new Scanner(System.in);
    try {
    this.deposita(Integer.parseInt(input.nextLine()));
    } catch (NumberFormatException x) {
    System.out.println(“Parametro Invalido”);
    } catch (RuntimeException x) {
    System.out.println(x.getMessage());
    }
    }

    protected void deposita(double valor) throws RuntimeException {
    if (valor < 0) {
    throw new RuntimeException(“Você nao pode depositar um valor negativo”);
    } else {
    this.saldo += valor;
    System.out.println(“Deposito Efetuado com Sucesso”);
    }
    }

    @Override
    public void sacaThrow () {
    System.out.println("Digite o valor que você quer sacar \n> ");
    Scanner input = new Scanner(System.in);
    try {
    this.saca(Integer.parseInt(input.nextLine()));
    } catch (NumberFormatException x) {
    System.out.println(“Parametro Invalido”);
    } catch (RuntimeException x) {
    System.out.println(x.getMessage());
    }
    }

    protected void saca (double valor) throws RuntimeException {

     if (valor < 0) {
         throw new RuntimeException("Valor Negativo");
     }
     if (valor > this.saldo) {
         throw new RuntimeException("Saldo Insuficiente");
     } else {
         this.saldo -= valor;
         System.out.println("Saque efetuado com sucesso");
     }
    

    }
    }[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

/**
*

  • @author Rafael
    */
    public class ContaCorrente extends ContaAbstrata {

}[/code]

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package containterface;

/**
*

  • @author Rafael
    */
    public class ContaPoupanca extends ContaAbstrata {

    protected String num_cartao_credito;

    public String getNum_cartao_credito() {
    return num_cartao_credito;
    }

    public void setNum_cartao_credito(String num_cartao_credito) {
    this.num_cartao_credito = num_cartao_credito;
    }

}
[/code]