Rutas
/
Java
Java
/
Ejercicios
/
El enigma de la calculadora
El enigma de la calculadora

El enigma de la calculadora

Ejercicio de aprendizaje

Introducción

Excepciones

El lenguaje de programación Java utiliza excepciones para gestionar errores y otros eventos excepcionales.

Qué es una excepción

Una excepción es un evento que ocurre durante la ejecución de un programa y que altera el flujo normal de las instrucciones. En Java, las excepciones se lanzan de forma explícita, y a ese acto se le llama lanzar una excepción. Al acto de gestionar una excepción se le llama capturar una excepción.

En Java, todas las excepciones son subclases de la clase Exception, que a su vez es una subclase de Throwable.

Java distingue dos tipos de excepciones:

  1. Excepciones comprobadas
  2. Excepciones no comprobadas
Excepciones comprobadas

Las excepciones comprobadas son condiciones excepcionales que una aplicación debería prever y de las que debería recuperarse. Un ejemplo de excepción comprobada es la FileNotFoundException, que se produce cuando un método intenta leer un fichero que no existe.

Este tipo de excepción se comprueba en tiempo de compilación: los métodos que lanzan excepciones comprobadas deben indicarlo en la firma del método, y el código que llama a un método que podría lanzar una excepción comprobada está obligado a gestionarla, o el código no compilará.

Todas las excepciones comprobadas son subclases de Exception que no extienden RuntimeException.

Excepciones no comprobadas

Las excepciones no comprobadas son condiciones excepcionales que una aplicación normalmente no puede prever ni de las que no puede recuperarse. Un ejemplo de excepción no comprobada es la NullPointerException, que se produce cuando un método espera un valor que no sea null pero recibe null.

Este tipo de excepción no se comprueba en tiempo de compilación: los métodos que lanzan excepciones no comprobadas no están obligados a indicarlo en la firma del método, y el código que llama a un método que podría lanzar una excepción no comprobada no está obligado a gestionarla.

Todas las excepciones no comprobadas heredan de RuntimeException, que a su vez es una extensión de Exception.

Lanzar excepciones

Un método en Java puede lanzar una excepción mediante la instrucción throw.

Lanzar una excepción comprobada

Cuando se lanza una excepción comprobada desde un método, es obligatorio indicarlo en la firma del método mediante la palabra clave throws, como se muestra en el ejemplo siguiente. Esto obliga al código que hace la llamada a prever que se podría lanzar una excepción y a gestionarla en consecuencia.

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
  }
}
Lanzar una excepción no comprobada

Cuando se lanza una excepción no comprobada desde un método, no es obligatorio indicarlo en la firma del método, aunque se admite.

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

    // rest of the method implementation
  }
}

Gestionar excepciones

La gestión de excepciones en Java se realiza con las palabras clave try, catch y finally.

  • Las instrucciones de código que podrían lanzar una excepción deben ir dentro de un bloque try.
  • Al bloque try le siguen uno o varios bloques catch que capturan las excepciones lanzadas en el bloque try.
  • Tras los bloques catch puede haber, de forma opcional, un bloque finally que siempre se ejecuta después del bloque try, independientemente de si se ha lanzado una excepción o no.

En el ejemplo siguiente se muestra cómo funcionan estas palabras clave:

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());
    }
  }
}

En este ejemplo, cuando no se lanza ninguna excepción, se imprime lo siguiente:

Withdrawing 10.0
Withdrawal succeeded
Current balance: 5.0

Sin embargo, si la instrucción bankAccount.withdraw(amount) lanzara una InsufficientBalanceException, se imprimiría lo siguiente:

Withdrawing 10.0
Withdrawal failed: insufficient balance
Current balance: 5.0

O bien, si bankAccount.withdraw(amount) lanzara una excepción no comprobada, se imprimiría lo siguiente:

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

Errores

Java también tiene una categoría aparte llamada errores, que son problemas graves y ajenos a la aplicación. Un ejemplo de error es el OutOfMemoryError, que se produce cuando una aplicación intenta usar más memoria de la disponible en el sistema.

Al igual que las excepciones no comprobadas, los errores no se comprueban en tiempo de compilación. La diferencia es que representan problemas a nivel de sistema y, por lo general, los lanza la máquina virtual de Java o el entorno en lugar de la aplicación. Por lo general, las aplicaciones no deberían intentar capturarlos ni gestionarlos.

Todos los errores en Java heredan de la clase Error.

Instrucciones

En este ejercicio vas a implementar la gestión de errores de una calculadora sencilla de números enteros. Para simplificar las cosas, se proporcionan métodos para calcular la suma, la multiplicación y la división.

El objetivo es tener una calculadora funcional que devuelva un String con el siguiente patrón: 16 + 51 = 67, cuando se le pasan los argumentos 16, 51 y +.

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 el método calculate para admitir algunas operaciones básicas

El método principal que implementarás en esta tarea será el método CalculatorConundrum.calculate(). Recibe tres argumentos. Los dos primeros argumentos, operand1 y operand2, son números enteros sobre los que se va a realizar una operación. El tercer argumento, operation, es de tipo String y para este ejercicio es necesario implementar las siguientes operaciones:

  • la suma, usando el String +
  • la multiplicación, usando el String *
  • la división, usando el String /

2. Gestiona las operaciones ilegales

Actualiza el método CalculatorConundrum.calculate() para gestionar las operaciones ilegales:

  • Cuando el argumento operation sea null, se debe lanzar una IllegalArgumentException con el mensaje Operation cannot be null.
  • Cuando el argumento operation sea "", se debe lanzar una IllegalArgumentException con el mensaje Operation cannot be empty.
  • Cuando el argumento operation sea cualquier operación distinta de +, * o /, se debe lanzar una IllegalOperationException con el mensaje 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. Gestiona la excepción que se lanza al dividir entre cero

En Java, intentar dividir entre cero lanza una ArithmeticException. Actualiza el método CalculatorConundrum.calculate() para capturar esta excepción y, a continuación, lanzar una IllegalOperationException con el mensaje Division by zero is not allowed y la ArithmeticException capturada como causa.

calculator.calculate(512, 0, "/");
// => throws IllegalOperationException with message "Division by zero is not allowed"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Java Exercism

¿Listo para empezar El enigma de la calculadora?

Regístrate en Exercism para aprender y dominar Java con 26 conceptos158 ejercicios y mentoría humana real, todo gratis.