Programación 1º – UD4 – Excepciones y Aserciones

Programación 1º – UD4 – Excepciones y Aserciones

Excepciones

En Java, una excepción es un error o situación inesperada que ocurre durante la ejecución de un programa. A diferencia de los errores de sintaxis (como errores de tipo o faltas de puntuación, que el compilador puede detectar), las excepciones son errores en tiempo de ejecución. Por ejemplo, si se intenta dividir un número entre cero o acceder a un índice fuera de los límites de un arreglo, Java puede lanzar una excepción.

  • Tipos de excepciones: Las excepciones en Java derivan de la clase base Throwable. Esta se divide en dos grandes categorías:
    • Error: Errores graves generalmente no manejables por el código del programador (por ejemplo, problemas de memoria).
    • Exception: Son excepciones comunes que pueden ser capturadas y manejadas por el código. La mayoría de las excepciones comunes, como ArithmeticException (error en operaciones matemáticas) o ArrayIndexOutOfBoundsException (acceso fuera de los límites de un arreglo), son subclases de Exception.

Jerarquía de las excepciones en Java:

Capturar Excepciones

Java proporciona un mecanismo para capturar y manejar excepciones usando las sentencias try, catch, y finally. Este enfoque ayuda a evitar que el programa se detenga bruscamente cuando ocurre un error.

  • try: Contiene el código que puede generar una excepción.
  • catch: Captura y maneja la excepción que ocurrió en el bloque try. Se puede tener múltiples bloques catch para diferentes tipos de excepciones.
  • finally: (Opcional) Este bloque se ejecuta siempre, haya o no ocurrido una excepción. Es útil para liberar recursos como archivos o conexiones de base de datos.

Sintaxis:

try {
// Código que puede generar una excepción
} catch (ExceptionTipo1 e) {
// Manejo de la excepción tipo 1
} catch (ExceptionTipo2 e) {
// Manejo de la excepción tipo 2
} finally {
// Código que se ejecutará siempre, haya o no excepción
}

Ejemplo:

try {
int result = 10 / 0; // Generará una ArithmeticException
} catch (ArithmeticException e) {
System.out.println("Error matemático: " + e.getMessage());
} finally {
System.out.println("Este bloque se ejecuta siempre.");
}

En este ejemplo, si ocurre una excepción como ArithmeticException, se capturará en el bloque catch, y el bloque finally siempre se ejecutará al final. Es decir, Java intenta dividir 10 entre 0. Cuando ve que eso no se puede, salta al catch y muestra un mensaje.

Delegación de Excepciones con throws

Si un método detecta una posible excepción pero no la maneja dentro de sí mismo, puede delegar la responsabilidad de manejarla a quien invoca dicho método, mediante la palabra clave throws.

Ejemplo de delegación:

public void metodo() throws IOException {
// Código que puede generar una excepción IOException
}

En este caso, quien llame a metodo() deberá manejar la posible excepción IOException mediante un bloque try-catch.

Ejemplo con delegación y manejo:

public void leerArchivo() throws IOException {
// Lógica que podría generar una IOException
}

public static void main(String[] args) {
try {
leerArchivo();
} catch (IOException e) {
System.out.println("Se produjo un error de entrada/salida.");
}
}

Aserciones

Las aserciones son una herramienta útil para asegurar que ciertas condiciones sean verdaderas en nuestro código. Son útiles para detectar errores lógicos en tiempo de ejecución durante el desarrollo y las pruebas.

  • Se emplea la palabra clave assert seguida de una condición booleana.
  • Si la condición es falsa, se lanza una excepción AssertionError.

Ejemplo de aserción:

int x = -1;
assert x > 0 : "x debería ser mayor que 0";

En este caso, si x es menor o igual a 0, se lanzará un AssertionError con el mensaje "x debería ser mayor que 0".

¿Cómo activar assert en NetBeans?

Las aserciones están desactivadas por defecto. Para activarlas, se debe usar la opción -ea al ejecutar el programa. Para hacerlo sigue estos pasos:

  1. Abre tu proyecto en NetBeans.
  2. En el menú de la izquierda, haz clic derecho sobre el nombre del proyecto.
  3. Selecciona “Propiedades”.
  4. En la ventana que aparece, ve a: Ejecutar (Run)
  5. En el campo “Opciones de la JVM” (VM Options), escribe: -ea

¿Cuándo usar aserciones?

Las aserciones son útiles en las siguientes situaciones:

  • Verificar que las suposiciones o invariantes del código son verdaderas.
  • Validar que las variables estén dentro de un rango esperado o que las condiciones de los métodos sean correctas.
  • Ayudar a detectar errores rápidamente durante el desarrollo.

Por ejemplo, podríamos usarlas para asegurarnos de que los índices de los arrays no sean negativos o que las variables de ciertas clases siempre estén en un estado válido.

PROGRAMACIÓN

Preguntas de Programación de DAM

Actividades de Programación UD4 - 6. Excepciones y Aserciones

Preguntas de Programación de 1ºDAM de la Unidad 4: Excepciones y Aserciones

1 / 20

¿Qué hace el bloque finally en este código?

try {
    int n = 5 / 0;
} catch (ArithmeticException e) {
    System.out.println("Error: " + e);
} finally {
    System.out.println("Siempre se ejecuta");
}

2 / 20

¿Qué hace esta aserción?

int x = 4;
assert x % 2 == 0;

3 / 20

¿Qué hace el throws en este código?

public int leerNumero() throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    return Integer.parseInt(br.readLine());
}

4 / 20

¿Cómo se indica que un método puede lanzar más de una excepción?

public void procesar() throws IOException, SQLException {
    // Código
}

5 / 20

¿Cuál es la salida del siguiente bloque con aserciones activadas?

int y = -10;
assert y > 0 : "Valor negativo";
System.out.println("Y: " + y);

6 / 20

¿Qué imprime este código con la aserción activada (-ea)?

int edad = -1;
assert edad >= 0 : "Edad inválida";
System.out.println("Edad: " + edad);

7 / 20

¿Qué hace esta aserción si se ejecuta con java -ea?

double pi = 3.14;
assert pi == 3.1416 : "Pi inexacto";

8 / 20

¿Qué excepción lanza este código?

String texto = null;
System.out.println(texto.length());

9 / 20

¿Qué ocurre al ejecutar este código?

int x = 10 / 0;
System.out.println("Resultado: " + x);

10 / 20

¿Qué hace este bloque try-catch?

try {
    int x = 10 / 2;
} catch (ArithmeticException e) {
    System.out.println("División por cero");
}

11 / 20

¿Cuál es el resultado si se produce una excepción y no se captura?

int[] arr = new int[2];
System.out.println(arr[5]);

12 / 20

¿Qué hace este código?

try {
    int n = Integer.parseInt("123");
    System.out.println(n);
} catch (Exception e) {
    System.out.println("Error");
}

13 / 20

¿Cuál es el problema de este código?

int num = Integer.parseInt("Hola");

14 / 20

¿Qué pasa si se lanza una excepción y no se captura ni se delega (throws)? (Asumiendo que b = 0)

public int dividir(int a, int b) {
    return a / b;
}

15 / 20

¿Qué ocurrirá al ejecutar este código?

try {
    int[] datos = new int[3];
    datos[3] = 10;
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("Índice fuera de rango");
}

16 / 20

¿Qué hace el siguiente bloque?

try {
    int num = Integer.parseInt("abc");
} catch (NumberFormatException e) {
    System.out.println("Error de formato");
}

17 / 20

¿Qué resultado da este código?

try {
    throw new Exception("¡Error!");
} catch (Exception e) {
    System.out.println(e.getMessage());
}

18 / 20

¿Cuál es la diferencia entre throw y throws en Java?

19 / 20

¿Qué hace esta sentencia?

assert false : "Esto nunca debería pasar";

20 / 20

¿Qué excepción lanza este código?

String[] nombres = {"Ana", "Luis"};
System.out.println(nombres[2]);

Your score is

0%

Actividades de programación

Actividad 1: División segura

Completa el bloque try-catch para evitar división por cero.

import java.util.Scanner;

public class DivisionSegura {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Introduce el numerador: ");
        int a = sc.nextInt();

        System.out.print("Introduce el denominador: ");
        int b = sc.nextInt();

        // TODO: Manejar excepción si el denominador es 0
        // Usa try-catch para atrapar ArithmeticException

        System.out.println("Programa finalizado.");
    }
}

import java.util.Scanner;

public class DivisionSegura {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print(“Introduce el numerador: “);
        int a = sc.nextInt();

        System.out.print(“Introduce el denominador: “);
        int b = sc.nextInt();

        try {
            int resultado = a / b;
            System.out.println(“Resultado: ” + resultado);
        } catch (ArithmeticException e) {
            System.out.println(“Error: No se puede dividir por cero.”);
        }

        System.out.println(“Programa finalizado.”);
    }
}

Actividad 2: Conversión de texto a número

Agrega el manejo para entradas no numéricas.

import java.util.Scanner;

public class ConversionTextoNumero {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Introduce un número: ");
        String entrada = sc.nextLine();

        // TODO: Convierte el texto a número y captura NumberFormatException si falla

        System.out.println("Programa finalizado.");
    }
}

import java.util.Scanner;

public class ConversionTextoNumero {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print(“Introduce un número: “);
        String entrada = sc.nextLine();

        try {
            int numero = Integer.parseInt(entrada);
            System.out.println(“Número introducido: ” + numero);
        } catch (NumberFormatException e) {
            System.out.println(“Error: Entrada no es un número válido.”);
        }

        System.out.println(“Programa finalizado.”);
    }
}

Actividad 3: Acceso a elementos de un array

Usa excepciones para evitar errores por acceder a índices no válidos.

import java.util.Scanner;

public class AccesoArreglo {
    public static void main(String[] args) {
        String[] frutas = {"Manzana", "Banana", "Pera", "Mango", "Uva"};
        Scanner sc = new Scanner(System.in);

        System.out.print("Introduce un índice (0-4): ");
        int indice = sc.nextInt();

        // TODO: Usa try-catch para manejar ArrayIndexOutOfBoundsException

        System.out.println("Fin del programa.");
    }
}

import java.util.Scanner;

public class AccesoArreglo {
    public static void main(String[] args) {
        String[] frutas = {“Manzana”, “Banana”, “Pera”, “Mango”, “Uva”};
        Scanner sc = new Scanner(System.in);

        System.out.print(“Introduce un índice (0-4): “);
        int indice = sc.nextInt();

        try {
            System.out.println(“Fruta seleccionada: ” + frutas[indice]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(“Error: Índice fuera de rango.”);
        }

        System.out.println(“Fin del programa.”);
    }
}

Actividad 4: Validación de edad con aserción

Usa assert para comprobar que la edad es válida (> 0).

public class ValidacionEdad {
    public static void main(String[] args) {
        int edad = -5; // Cambia este valor para probar

        // TODO: Usa assert para verificar que la edad es mayor que 0

        System.out.println("Edad válida: " + edad);
    }
}

public class ValidacionEdad {
    public static void main(String[] args) {
        int edad = -5; // Cambia este valor para probar

        assert edad > 0 : “La edad debe ser mayor que cero”;

        System.out.println(“Edad válida: ” + edad);
    }
}

Actividad 5: Lanza y delega tus propias excepciones

Crea una excepción personalizada y úsala para validar un nombre.

1. Clase de excepción personalizada (NombreInvalidoException.java):

// TODO: Extiende Exception y crea un constructor con mensaje personalizado
public class NombreInvalidoException extends Exception {

}

2. Clase principal con validación (VerificarNombre.java):

import java.util.Scanner;

public class VerificarNombre {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Introduce tu nombre: ");
        String nombre = sc.nextLine();

        try {
            // TODO: Llama al método verificarNombre
            System.out.println("Nombre válido: " + nombre);
        } catch (NombreInvalidoException e) {
            System.out.println("¡Error! " + e.getMessage());
        }
    }

    // TODO: Lanza NombreInvalidoException si el nombre es muy corto o nulo
    public static void verificarNombre(String nombre) throws NombreInvalidoException {
        
    }
}

1. Clase de excepción personalizada:

public class NombreInvalidoException extends Exception {
    public NombreInvalidoException(String mensaje) {
        super(mensaje);
    }
}

2. Clase principal con método que lanza la excepción:

import java.util.Scanner;

public class VerificarNombre {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print(“Introduce tu nombre: “);
        String nombre = sc.nextLine();

        try {
            verificarNombre(nombre);
            System.out.println(“Nombre válido: ” + nombre);
        } catch (NombreInvalidoException e) {
            System.out.println(“¡Error! ” + e.getMessage());
        }
    }

    public static void verificarNombre(String nombre) throws NombreInvalidoException {
        if (nombre == null || nombre.trim().isEmpty()) {
            throw new NombreInvalidoException(“El nombre no puede estar vacío.”);
        }

        if (nombre.length() < 3) {
            throw new NombreInvalidoException(“El nombre debe tener al menos 3 caracteres.”);
        }
    }
}