Track
/
Java
Java
/
Esercizi
/
L'enigma della calcolatrice
L'enigma della calcolatrice

L'enigma della calcolatrice

Esercizio di apprendimento

Introduzione

Eccezioni

Il linguaggio di programmazione Java usa le eccezioni per gestire gli errori e altri eventi eccezionali.

Cos'è un'eccezione

Un'eccezione è un evento che si verifica durante l'esecuzione di un programma e che interrompe il normale flusso delle istruzioni. In Java le eccezioni vengono sollevate esplicitamente, e l'atto di sollevare un'eccezione si chiama lanciare un'eccezione. L'atto di gestire un'eccezione si chiama catturare un'eccezione.

In Java, tutte le eccezioni sono sottoclassi della classe Exception, che a sua volta è una sottoclasse di Throwable.

Java distingue due tipi di eccezioni:

  1. Eccezioni controllate
  2. Eccezioni non controllate
Eccezioni controllate

Le eccezioni controllate sono condizioni eccezionali che un'applicazione dovrebbe prevedere e dalle quali dovrebbe riprendersi. Un esempio di eccezione controllata è FileNotFoundException, che si verifica quando un metodo cerca di leggere un file che non esiste.

Questo tipo di eccezione viene controllato in fase di compilazione: i metodi che lanciano eccezioni controllate devono specificarlo nella loro firma, ed il codice che chiama un metodo che potrebbe lanciare un'eccezione controllata deve gestirla, altrimenti non verrà compilato.

Tutte le eccezioni controllate sono sottoclassi di Exception che non estendono RuntimeException.

Eccezioni non controllate

Le eccezioni non controllate sono condizioni eccezionali che un'applicazione di solito non può prevedere e dalle quali non può riprendersi. Un esempio di eccezione non controllata è NullPointerException, che si verifica quando un metodo che si aspetta un valore non nullo riceve invece null.

Questo tipo di eccezione non viene controllato in fase di compilazione: i metodi che lanciano eccezioni non controllate non devono specificarlo nella loro firma, ed il codice che chiama un metodo che potrebbe lanciare un'eccezione non controllata non è tenuto a gestirla.

Tutte le eccezioni non controllate ereditano da RuntimeException, che a sua volta estende Exception.

Lanciare eccezioni

Un metodo in Java può lanciare un'eccezione usando l'istruzione throw.

Lanciare un'eccezione controllata

Quando si lancia un'eccezione controllata da un metodo, è necessario specificarlo nella firma del metodo usando la parola chiave throws, come mostra l'esempio seguente. Questo obbliga il codice chiamante a prevedere che possa essere lanciata un'eccezione e a gestirla di conseguenza.

public class InsufficientBalanceException extends Exception {

}

public class BankAccount {
  public void withdraw(double amount) throws InsufficientBalanceException {
    if (balance < amount) {
      throw new InsufficientBalanceException();
    }

    // rest of the method implementation
  }
}
Lanciare un'eccezione non controllata

Quando si lancia un'eccezione non controllata da un metodo, non è necessario specificarlo nella firma del metodo, anche se è supportato.

public class BankAccount {
  public void withdraw(double amount) {
    if (amount < 0) {
      throw new IllegalArgumentException("Cannot withdraw a negative amount");
    }

    // rest of the method implementation
  }
}

Gestire le eccezioni

In Java la gestione delle eccezioni avviene con le parole chiave try, catch e finally.

  • Le istruzioni di codice che potrebbero lanciare un'eccezione dovrebbero essere racchiuse in un blocco try.
  • Il blocco try è seguito da uno o più blocchi catch che catturano le eccezioni lanciate nel blocco try.
  • I blocchi catch sono facoltativamente seguiti da un blocco finally che viene sempre eseguito dopo il blocco try, indipendentemente dal fatto che sia stata lanciata o meno un'eccezione.

L'esempio seguente mostra come funzionano queste parole chiave:

public class ATM {
  public void withdraw(BankAccount bankAccount, double amount) {
    try {
      System.out.println("Withdrawing " + amount);
      bankAccount.withdraw(amount);
      System.out.println("Withdrawal succeeded");
    } catch (InsufficientBalanceException) {
      System.out.println("Withdrawal failed: insufficient balance");
    } catch (RuntimeException e) {
      System.out.println("Withdrawal failed: " + e.getMessage());
    } finally {
      System.out.println("Current balance: " + bankAccount.getBalance());
    }
  }
}

In questo esempio, quando non viene lanciata alcuna eccezione, viene stampato quanto segue:

Withdrawing 10.0
Withdrawal succeeded
Current balance: 5.0

Se invece l'istruzione bankAccount.withdraw(amount) lancia un'InsufficientBalanceException, viene stampato quanto segue:

Withdrawing 10.0
Withdrawal failed: insufficient balance
Current balance: 5.0

Oppure, se bankAccount.withdraw(amount) lancia un'eccezione non controllata, viene stampato quanto segue:

Withdrawing -10.0
Withdrawal failed: Cannot withdraw a negative amount
Current balance: 5.0

Errori

Java ha anche una categoria separata chiamata Errori, che sono problemi gravi esterni all'applicazione. Un esempio di errore è OutOfMemoryError, che si verifica quando un'applicazione cerca di usare più memoria di quanta ne sia disponibile nel sistema.

Come le eccezioni non controllate, gli errori non vengono controllati in fase di compilazione. La differenza è che rappresentano problemi a livello di sistema e sono generalmente lanciati dalla Java Virtual Machine o dall'ambiente invece che dall'applicazione. Generalmente le applicazioni non dovrebbero tentare di catturarli o gestirli.

Tutti gli errori in Java ereditano dalla classe Error.

Istruzioni

In questo esercizio costruirai la gestione degli errori per una semplice calcolatrice di numeri interi. Per semplificare le cose, i metodi per calcolare addizione, moltiplicazione e divisione sono già forniti.

L'obiettivo è avere una calcolatrice funzionante che restituisce una stringa con il seguente formato: 16 + 51 = 67, quando riceve come argomenti 16, 51 e +.

CalculatorConundrum calculator = new CalculatorConundrum();

calculator.calculate(16, 51, "+");
// => returns "16 + 51 = 67"

calculator.calculate(32, 6, "*");
// => returns "32 * 6 = 192"

calculator.calculate(512, 4, "/");
// => returns "512 / 4 = 128"

1. Implementa il metodo calculate per supportare alcune operazioni di base

Il metodo principale da implementare in questa attività sarà il metodo CalculatorConundrum.calculate(). Richiede tre argomenti. I primi due argomenti, operand1 e operand2, sono numeri interi su cui verrà eseguita un'operazione. Il terzo argomento, operation, è di tipo String e per questo esercizio è necessario implementare le seguenti operazioni:

  • addizione usando la stringa +
  • moltiplicazione usando la stringa *
  • divisione usando la stringa /

2. Gestisci le operazioni non valide

Aggiorna il metodo CalculatorConundrum.calculate() per gestire le operazioni non valide:

  • Quando l'argomento operation è null, va lanciata un'IllegalArgumentException con il messaggio Operation cannot be null.
  • Quando l'argomento operation è "", va lanciata un'IllegalArgumentException con il messaggio Operation cannot be empty.
  • Quando l'argomento operation è un'operazione diversa da +, * o /, va lanciata un'IllegalOperationException con il messaggio Operation '{operation}' does not exist.
calculator.calculate(10, 1, null);
// => throws IllegalArgumentException with message "Operation cannot be null"

calculator.calculate(10, 1, "");
// => throws IllegalArgumentException with message "Operation cannot be empty"

calculator.calculate(10, 1, "-");
// => throws IllegalOperationException with message "Operation '-' does not exist"

3. Gestisci l'eccezione lanciata quando si divide per zero

In Java, tentare di dividere per zero lancia un'ArithmeticException. Aggiorna il metodo CalculatorConundrum.calculate() per intercettare questa eccezione e lanciare poi un'IllegalOperationException con il messaggio Division by zero is not allowed e l'ArithmeticException intercettata come causa.

calculator.calculate(512, 0, "/");
// => throws IllegalOperationException with message "Division by zero is not allowed"
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Java Exercism

Vuoi iniziare L'enigma della calcolatrice?

Iscriviti a Exercism per imparare e padroneggiare Java con 26 concetti158 esercizi e il mentoring di persone reali, tutto gratis.