Sie sind auf Seite 1von 15

Programación Orientado a Objetos IS-142

Ingeniería de Sistemas - UNSCH

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

conjunto. Para el primer caso, es necesario este código


catch(ArrayIndexOutOfBoundsException e){ },
para el segundo catch (ArrayException e){} y para el último catch (Exception e){ }. En la
práctica no es recomendable hacer usar de manejadores de excepciones demasiado
generales, como la del último caso. Las excepciones son parte de Java, y es muy común
usarlos en las operaciones E/S, ya que es donde más probabilidad hay de que se lanze
una.

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.

Lanzar nuestras propias excepciones


Si hacemos métodos propios, podemos lanzar excepciones en caso de que algo vaya mal.
Estas excepciones pueden ser las de java o bien unas que creemos nosotros.
Para crear nuestra excepción, basta con hacer una clase que herede de Exception.
public class MiExcepcion extends Exception
{
public MiExcepcion(...) {
...
}
public void miPropioMetodo(...) {
...
}
}
Nuestro método que lanza esta excepción, o una de java, debe declararse con un throws
public class MiClase
{
public int miMetodoQueLanzaExcepcionSiHayFallo (...) throws MiExcepcion
{
ejecutoMiCodigo();
// si hay fallo, se lanza la excepcion.
if (hayFallo())
throw new MiExcepcion(...);
return resultado;
}
}
Para lanzar la excepción, como vemos en ese código, basta con hacer un new de
MiExcepción y lanzarla con throw.

¿Cuándo lanzar excepciones?


Cuando estamos codificando un método puede que nos fallen cosas y no podamos seguir
haciendo lo que pretendemos. ¿Debemos lanzar siempre una excepción es estos casos? ¿o
debemos mostrar el error por pantalla? ¿quizás debemos tratar de solventar el error y no
hacer nada?.
• Si el método es un método que pensamos reutilizar mucho, en muchos proyectos
distintos, es mejor lanzar una excepción. Dejamos la decisión de qué hacer en
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH

caso de error al que utilice nuestro método. Nosotros simplemente le informamos


que ha ocurrido un error para que él lo trate.
• Si el método es de la parte de alto nivel de nuestra aplicación, debemos tratar
directamente el error y no lanzar la excepción. En este nivel alto debemos saber
qué hace nuestra aplicación con los errores: mostrarlos en una ventana de pop-up,
escribirlos como salida de texto, ignorarlos, etc.

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.

Lanzamiento de excepciones: throw - throws


Muchas veces el programador dentro de un determinado método deberá comprobar si
alguna condición de excepción se cumple, y si es así lanzarla. Para ello se utilizan las
palabras reservadas throw y throws.
Por una parte la excepción se lanza mediante la sentencia throw:

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.

Ejemplo de gestión de excepciones

// Crear una excepción personalizada


public class MiExcepcion extends Exception {
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH

MiExcepcion(){
super(); // constructor por defecto de Exception
}
MiExcepcion( String cadena ){
super( cadena ); // constructor parámetro de Exception
}

public class Lanzadora {


void lanzaSiNegativo( int param ) throws MiExcepcion {
if ( param < 0 )
throw new MiExcepcion( "Numero negativo" );
}

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Excepciones {


public static void main( String[] args ) throws FileNotFoundException, IOException {
// Para leer un fichero
Lanzadora lanza = new Lanzadora();
FileOutputStream entrada = null;
FileInputStream salida = null;
entrada = new FileOutputStream( "fich.txt" );
entrada.write(-1);
entrada.write(2);
entrada.write(-1);

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

System.out.println( "Excepcion: " + e.getMessage() );


} finally {
if ( entrada != null )
try {
entrada.close(); // Siempre queda cerrado
} catch ( Exception e ) {
System.out.println( "Excepcion: " + e.getMessage() );
}
System.out.println( "Fichero cerrado." );
} }}
Excepciones que incorpora Java
a.) Clases de Error
LinkageError: Una clase no satisface la dependencia que tiene respecto a otra.
• ClassCircularityError: Se detectó una herencia circular entre clases.
• ClassFormatError: Una clase cargada no ha sido incompletamente descrita.
o UnsupportedClassVersionError: La versión de una clase no es correcta.
• ExceptionInInitializerError: Error al iniciar un miembro static.
• IncompatibleClassChangeError: En una clase, su interfaz no es igual al declarado
o AbstractMethodError: Se ha invocado un método abstracto.
o IllegalAccessError: La aplicación intentó acceder a algún miembro no
visible.
o InstantiationError: Se intentó instanciar una clase abstracta o interfaz.
o NoSuchFieldError: No se encontró determinado atributo.
o NoSuchMethodError: No se encontró determinado método.
• NoClassDefFoundError: No se encontró una clase cuando se necesitaba.
• UnsatisfiedLinkError: Se encontró un enlace insatisfecho en un método nativo.
• VerifyError: Se ha producido un error de verificación al cargar una clase.
ThreadDeath: Se ha lanzado en el thread víctima tras llamar a stop().
VirtualMachineError: La máquina virtual se ha averiado o quedado sin recursos.
• InternalError: Error interno en tiempo de ejecución.
• OutOfMemoryError: El lector ha agotado la memoria.
• StackOverflowError: Desbordamiento de pila. ¿Recursión infinita?.
• UnknownError: Grave error desconocido.
b.) Clases de Exception
CloneNotSupportedException: No se pudo copiar un objeto mediante clone().
IllegalAccessException: Algún método invocado es no visible.
InstantiationException: Se ha intentado instanciar una interfaz o una clase abstracta.
InterruptedException: Cuando se invoca a interrupt() sobre un thread dormido.
NoSuchFieldException: La clase no tiene un atributo con ese nombre.
NoSuchMethodException: La clase no tiene un método con ese nombre.
c.) Clases de RuntimeException
ArithmeticException: Error de cálculo (como división por cero...).
ArrayStoreException: Intento de almacenar un objeto equivocado en un vector.
ClassCastException: Intento de conversión inválida.
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH

IllegalArgumentException: Se ha pasado un argumento inválido a un método:


• IllegalThreadStateException: Un thread no estaba en el estado adecuado.
• NumberFormatException: Una cadena contenedora de un número, no lo contiene.
IllegalMonitorStateException: Se ha usado wait/notify fuera de código sincronizado.
IllegalStateException: Método invocado en un momento inapropiado.
IndexOutOfBoundsException: Acceso a un vector fuera de sus límites:
• ArrayIndexOutOfBoundsException: Idem, para una matriz.
• StringIndexOutOfBoundsException: Idem, para una cadena.
NegativeArraySizeException: Intento de creación de un vector de tamaño negativo.
NullPointerException: Se ha usado una referencia null para acceder a un campo.
SecurityException: Algo ha sido vedado por el sistema de seguridad.
UnsupportedOperationException: Una operación invocada no se soporta.
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

public class Excepcion1 {


public static void main(String[] args) {
String str1="101";
String str2="2";
String respuesta;

int numerador, denominador, cociente;


try{
cociente=calcular(str1, str2);
respuesta=String.valueOf(cociente);
}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);
}
static int calcular(String str1, String str2)throws ExcepcionIntervalo,
NumberFormatException, ArithmeticException{
int num=Integer.parseInt(str1);
int den=Integer.parseInt(str2);
if((num>100)||(den<-5)){
throw new ExcepcionIntervalo("Números fuera del intervalo");
}
return (num/den);
}

public class Excepcion2 {


public static void main(String[] args) {
String str1="120";
String str2="3";
String respuesta;
int numerador, denominador, cociente;
try{
numerador=Integer.parseInt(str1);
denominador=Integer.parseInt(str2);
rango(numerador, denominador);
cociente=numerador/denominador;
respuesta=String.valueOf(cociente);
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);
}

static void rango(int num, int den)throws ExcepcionIntervalo{


if((num>100)||(den<-5)){
throw new ExcepcionIntervalo("Números fuera de rango");
}
}

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

Las clases de flujo están organizadas de la siguiente forma:


Reader
BufferedReader
InputStreamReader
FileReader
Writer
PrintWriter
FileWriter

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

} catch (IOException ex) {


System.out.println("Error escribiendo los datos");
System.exit(1);
}}}}}

El siguiente código lee el archivo anterior.

public class LeerArchivo {


public static void main(String[] args) {
try
{ FileInputStream fis = new FileInputStream("archivo.txt ");
for (int n = fis.read(); n != -1; n = fis.read())
{ System.out.write(n);//escribe en pantalla el dato
}
}
catch (IOException ex)
{ System.err.println(ex);
}
}
}

El siguiente código crea un archivo e introduce datos, mediante campos.

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Escritura {


public static void main( String args[] )throws IOException{
Scanner leer = new Scanner(System.in);
DataOutputStream Archi = null;
int i;

String nombre=new String("");


int calif1;
int calif2;
int calif3;
double promedio;
try{
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH

for (i=0; i<1; i++){


Archi = new DataOutputStream( new FileOutputStream("../Archivo1.dat",true) );
System.out.println("Escribe Nombre: ");
nombre = leer.next();
System.out.println("Ingrese Calificacion 1: ");
calif1 = leer.nextInt();
System.out.println("Ingrese Califiación 2");
calif2 = leer.nextInt();
System.out.println("Ingrese Calificacion 3");
calif3 = leer.nextInt();

Archi.writeUTF(nombre);
Archi.writeInt(calif1);
Archi.writeInt(calif2);
Archi.writeInt(calif3);
Archi.close();
}
}
catch(FileNotFoundException fnfe) {}
catch (IOException ioe) {}
}
}

El siguiente código lee el archivo anterior.


import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Lectura {


public static void main( String args[] )throws IOException{
DataInputStream Archi = null;
int matricula=0;
String nombre=new String("");
int calif1;
int calif2;
int calif3;
double promedio;
try{
Archi = new DataInputStream( new FileInputStream("../Archivo1.dat") );
while (true){
Programación Orientado a Objetos IS-142
Ingeniería de Sistemas - UNSCH

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+" ");

int suma = calif1 + calif2 + calif3;


promedio = suma/3;
System.out.println("El promedio es: "+promedio);
}
}
catch(FileNotFoundException fnfe) {}
catch (IOException ioe) {}
Archi.close();
}
}

Ejercicios
1. Implementar en código java un programa que guardar un objeto en un archivos
TAREA
1. Implementar un sistema para una tienda.

Das könnte Ihnen auch gefallen