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, comoArithmeticException(error en operaciones matemáticas) oArrayIndexOutOfBoundsException(acceso fuera de los límites de un arreglo), son subclases deException.
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 bloquetry. Se puede tener múltiples bloquescatchpara 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
assertseguida 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:
- Abre tu proyecto en NetBeans.
- En el menú de la izquierda, haz clic derecho sobre el nombre del proyecto.
- Selecciona “Propiedades”.
- En la ventana que aparece, ve a: Ejecutar (Run)
- 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.
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.”);
}
}
}