Beruflich Dokumente
Kultur Dokumente
Excepciones en Java
En todo programa existen errores inesperados en tiempo de ejecución, y también errores
que no consideramos debido a nuestra propia inexperiencia como programadores. Unos
de estos errores ocurren por ejemplo, al intentar acceder a un elemento del arreglo que
está fuera del límite de nuestro arreglo, o cuando intentamos acceder a un archivo
inexistente, entre otros. Normalmente estos errores interrumpen el flujo de ejecución de
nuestros programas, hasta el extremo de provocar la terminación del programa en forma
inmediata.
Java hace uso de las excepciones para poder controlar los errores en tiempo de ejecución.
En Java, casi todo los tipos de errores que puedan surgir en tiempo de ejecución lanzan
excepciones, es decir, cuando ocurre un error dentro de un método de Java, este método
crea un objeto Exception, dicho objeto contiene información sobre la excepción, que
incluye su tipo y el estado del programa cuando ocurrió el error. El sistema de ejecución
es el responsable de buscar algún código para manejar el error. El manejo de excepciones
en Java sigue una estructura como esta:
try {
//Codigo donde puede ocurrir un error
}
catch (ExcepcionA ex) { // Que se va a hacer en caso que se lanze una ExcepcionA }
...
catch (ExcepcionZ ex) { // Que se va a hacer en caso que se lanze una Excepcion Z }
Dentro del bloque try{ } viene encerrado la parte del programa que se desea manejar sus
excepciones.
El código dentro de algún catch (TipoExcepcion e) se ejecuta en caso se que lanze una
excepción TipoExcepcion o que pertenezca al grupo TipoExcepcion.
El sistema de ejecución Java busca hacia atrás en la pila de llamadas para encontrar el
método que esté interesado en manejar una excepción particular. Es decir si se lanza una
excepción en el método , pero si no está interesado en manejar dicha excepción,
entonces el sistema de ejecución Java ve quién llamó a (supongamos que si existe, y es
el método ), entonces se regresa a y ve si está interesado en dicha excepción, y así
consecutivamente hasta llegar al método principal de nuestra aplicación.
En caso de no encontrar alguien que quiera manejarlo, comúnmente Java manda una lista
de mensajes en nuestra ventana de consola, y en muchos casos se termina la ejecución de
nuestro programa. Cuando manejamos excepciones, podemos manejar excepciones en
forma específica (por ejemplo, usar un índice que está fuera de los límites de nuestro
arreglo), o manejar una excepción de cierta categoría (por ejemplo, una excepción
lanzada por mal uso de un arreglo de datos), o manejar todas las excepciones en su
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
Si el código dentro del bloque try genera varios tipos de excepciones, podemos poner
varios bloques catch, para capturar por separado cada tipo. Por ejemplo,
try
{
codigo();
masCodigo();
yMas();
}
catch (IOException e)
{
trataIOException(e);
}
catch (DataFormatException e2)
{
trataDataFormatException(e2);
}
catch (...)
finally
Muchas veces es importante que se ejecute algo tanto si se produce una excepción como
si no. Por ejemplo, si abrimos un fichero para leerlo, es importante asegurarse que luego
lo cerramos. Si nos conectamos a una base de datos para hacer una consulta, suele ser
importante cerrar después la conexión. Esto debe hacerse independientemente de que las
operaciones de lectura tengan o no éxito.
Para ello, try-catch admite un tercer bloque finally. Este bloque finally se ejecutará
siempre, pase lo que pase, cuando se termine el try o el catch.
try
{
abreFichero();
leeFichero();
return;
}
catch (Exception e)
{
trataError(e);
}
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
finally
{
cierraFichero();
}
Si al abrir el fichero o al leerlo salta una excepción, se tratará la excepción y luego se
ejecutará el finally, cerrando el fichero. Si no hay excepción, después del try, se ejecutará
también el finally y se cerrará el fichero.
Tipos de excepciones
Existen varios tipos fundamentales de excepciones:
• Error: Excepciones que indican problemas muy graves, que suelen ser no
recuperables y no deben casi nunca ser capturadas.
• Exception: Excepciones no definitivas, pero que se detectan fuera del tiempo de
ejecución.
• RuntimeException: Excepciones que se dan durante la ejecución del programa.
Funcionamiento
Para que el sistema de gestión de excepciones funcione, se ha de trabajar en dos partes de
los programas:
• Definir qué partes de los programas crean una excepción y bajo qué condiciones.
Para ello se utilizan las palabras reservadas throw y throws.
• Comprobar en ciertas partes de los programas si una excepción se ha producido, y
actuar en consecuencia. Para ello se utilizan las palabras reservadas try, catch y
finally.
if ( condicion_de_excepcion == true )
throw new miExcepcion();
Aquellos métodos que pueden lanzar excepciones, deben conocer cuáles son esas
excepciones en su declaración. Para ello se utiliza la sentencia throws:
tipo_devuelto miMetodoLanzador() throws miExcep1, miExcep2 {
// Codigo capaz de lanzar excepciones miExcep1 y miExcep2
}
Se puede observar que cuando se pueden lanzar en el método más de una excepción se
deben indicar en su declaración separadas por comas.
MiExcepcion(){
super(); // constructor por defecto de Exception
}
MiExcepcion( String cadena ){
super( cadena ); // constructor parámetro de Exception
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
int leo;
try {
salida = new FileInputStream( "fich.txt" );
while ( ( leo = salida.read() ) != -1 )
lanza.lanzaSiNegativo( leo );
entrada.close();
System.out.println(leo);
System.out.println( "Todo fue bien" );
} catch ( MiExcepcion e ){ // Personalizada
System.out.println( "Excepcion: " + e.getMessage() );
} catch ( IOException e ){ // Estándar
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
Excepciones Predefinidas
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
Los nombres de las excepciones indican la condición de error que representan. Las
siguientes son las excepciones predefinidas más frecuentes que se pueden encontrar:
ArithmeticException
Las excepciones aritméticas son típicamente el resultado de división por 0:
int i = 12 / 0;
NullPointerException
Se produce cuando se intenta acceder a una variable o método antes de ser definido:
class Hola extends Applet {
Image img;
paint( Graphics g ) {
g.drawImage( img,25,25,this );
}
}
IncompatibleClassChangeException
El intento de cambiar una clase afectada por referencias en otros objetos, específicamente
cuando esos objetos todavía no han sido recompilados.
ClassCastException
El intento de convertir un objeto a otra clase que no es válida.
y = (Prueba)x; // donde x no es de tipo Prueba
NegativeArraySizeException
Puede ocurrir si hay un error aritmético al cambiar el tamaño de un array.
OutOfMemoryException
¡No debería producirse nunca! El intento de crear un objeto con el operador new ha
fallado por falta de memoria. Y siempre tendría que haber memoria suficiente porque el
garbage collector se encarga de proporcionarla al ir liberando objetos que no se usan y
devolviendo memoria al sistema.
NoClassDefFoundException
Se referenció una clase que el sistema es incapaz de encontrar.
ArrayIndexOutOfBoundsException <
Es la excepción que más frecuentemente se produce. Se genera al intentar acceder a un
elemento de un array más allá de los límites definidos inicialmente para ese array.
UnsatisfiedLinkException
Se hizo el intento de acceder a un método nativo que no existe. Aquí no existe un método
a.kk()
class A {
native void kk();
}
y se llama a a.kk(), cuando debería llamar a A.kk().
Ejemplos:
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
}catch(NumberFormatException ex){
respuesta="Se han introducido caracteres no numéricos";
}catch(ArithmeticException ex){
respuesta="División entre cero";
}catch(ExcepcionIntervalo ex){
respuesta=ex.getMessage();
}
System.out.println(respuesta);
}
Ejercicios
1. Cree su propia Excepción para la división por cero en una calculadora.
2. Cree su propia Excepción para suma de dos números positivos.
Archivos
Archivos de texto
Si se desea procesar datos de un archivo existente, se debe:
1. Abrir el archivo
2. Leer o introducir los datos en las variables, un elemento a la vez
3. Cerrar el archivo cuando se termine de trabajar con él
Para transferir algunos datos de ciertas variables a un archivo, se debe:
1. Abrir el archivo
2. Extraer o escribir los elementos en la secuencia requerida
3. Cerrar el archivo cuando se termine de trabajar con él
Al leer un archivo, todo lo que puede hacerse es leer el siguiente elemento. Si, por
ejemplo, quisiéramos examinar el último elemento, tendríamos que codificar un ciclo
para leer cada uno de los elementos en turno, hasta llegar al elemento requerido. Para
muchas tareas, es conveniente visualizar un archivo como una serie de líneas de texto,
cada una compuesta por un número de caracteres y que termina con el carácter de fin de
línea. Un beneficio de esta forma de trabajo es la facilidad de transferir archivos entre
aplicaciones. Así se podría crear un archivo ejecutando un programa en Java y después
cargarlo en un procesador de palabras, editor de texto o correo electrónico.
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
Para procesar archivos se utilizan las clases BufferedReader y PrintWriter para leer y
escribir líneas de texto, y para la entrada que no provenga de archivos (desde el teclado y
páginas Web) también se utiliza InputSreamReader.
Los programas que utilizan archivos deben contener la instrucción: import java.io.*;
"Búfer" significa que, el software lee un gran trozo de datos del dispositivo de
almacenamiento externo y lo guarda en la RAM, de tal forma que invocaciones sucesivas
de los métodos que necesitan leer una pequeña cantidad de datos del dispositivo de
almacenamiento de archivos puedan obtener rápidamente los datos de la RAM. Por lo
tanto, un búfer actúa como un amortiguador entre el dispositivo de almacenamiento y el
programa.
Escribir un archivo de texto requiere el uso apropiado de clases para crear el flujo de
salida y llamar a los métodos para escribir los datos. La clase FileWriter representa un
archivo texto de salida. La clase PrintWriter ofrece los métodos print y println similares a
los de System. Después de terminar de crear o utilizar un archivo es muy recomendable
que se cierre, ya que de lo contrario no se garantiza que los datos estarán almacenados en
un dispositivo semi-permanente.
Ejemplos;
El siguiente código crea un archivo e introduce datos.
public class CrearArchivo {
public static void main(String[] args) throws FileNotFoundException {
FileOutputStream fout = null;
try {
fout = new FileOutputStream("archivo.txt", true);
} catch (IOException ex) {
System.out.println("Error al crear el fichero");
System.out.println(ex.getMessage());
System.exit(1);
}
String[] arreglo = {"\nJennifer\n", "Maria\n", "Lina"};
for(int i = 0; i < arreglo.length; ++i) {
for( int j = 0; j < arreglo[i].length(); ++j ) {
try {
fout.write( (byte) ( arreglo[ i ].charAt( j ) ) );
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
Archi.writeUTF(nombre);
Archi.writeInt(calif1);
Archi.writeInt(calif2);
Archi.writeInt(calif3);
Archi.close();
}
}
catch(FileNotFoundException fnfe) {}
catch (IOException ioe) {}
}
}
nombre = Archi.readUTF();
System.out.println("Nombre: "+nombre+" ");
calif1= Archi.readInt();
System.out.println("Calificacion 1: "+calif1+" ");
calif2= Archi.readInt();
System.out.println("Calificacion 2: "+calif2+" ");
calif3= Archi.readInt();
System.out.println("Calificacion 3: "+calif3+" ");
Ejercicios
1. Implementar en código java un programa que guardar un objeto en un archivos
TAREA
1. Implementar un sistema para una tienda.