Publicado el 6 de Septiembre del 2017
573 visualizaciones desde el 6 de Septiembre del 2017
38,3 KB
10 paginas
Creado hace 18a (01/06/2005)
Clase adicional 10
Temas
o Excepción
o Flujo
o Tipos de excepciones
o Detectar una excepción
o Detectar varias excepciones
o Crear una excepción propia
o Arrojar una excepción
o Entrada, salida y error tradicionales
o Flujos de entrada y salida
o Ejemplo
o Búsqueda lineal
o Búsqueda binaria
o Árbol binario
o Búsqueda binaria
o Problemas de la clase adicional
o Problema de diseño
Excepción
El término excepción es una forma abreviada de "evento excepcional" que se
produce durante la ejecución de un programa que interrumpe el flujo normal de
instrucciones. Cuando JVM se encuentra con una excepción:
o detiene el procesado del código en el que está trabajando
o crea un tipo concreto de objeto de excepción
o ejecuta la rutina que gestiona dicha excepción
Tipos de excepciones
Existen dos tipos de excepciones en Java: comprobadas y sin comprobar.
Las excepciones comprobadas se producen por algún error en el entorno en el que se
desarrolla el código. Por ejemplo, si el código intenta leer información de un archivo
que no existe, el programa arrojará una excepción IOException. Una excepción
comprobada se escapa del control del programador: puede producirse incluso si el
código no contiene ni un solo error. Por lo tanto, debe estar preparado para obtener
excepciones comprobadas en el código: podrá detectarlas o arrojarlas.
Las excepciones no comprobadas suelen producirse por errores de programación. En
este caso, lo más indicado es corregir el programa. Por este motivo, no
se da por hecho que se gestionarán todas en el código (se deben evitar en primer lugar).
Por ejemplo, si el código intenta leer el décimo elemento de un array de tamaño 9, el
programa arrojará una excepción ArrayIndexOutOfBoundException.
Detectar una excepción
Si cree que determinadas partes del código podrían generar una excepción, encierre
dicho código dentro de un bloque try…catch. Éste es el formato
try
{ código }
catch (XYException e)
{ gestor de la excepción XYException }
finally { ejecutar siempre }
o Si cualquier parte del código dentro del bloque try crea una excepción, el
programa saltará el resto del código del bloque try y ejecutará el código
del gestor dentro del bloque catch.
o Si no se produce ninguna excepción, el programa recorrerá todo el código
o Independientemente de lo que ocurra dentro del bloque try, el código
del bloque try y saltará el bloque catch.
dentro del bloque finally siempre se ejecutará.
¿Qué debe hacer si detecta una excepción? El método más sencillo es imprimirla. Hay
tres formas de hacerlo
getMessage() devuelve una cadena que describe la excepción que se ha producido
toString() devuelve una cadena compuesta por el nombre de la clase de la excepción
concreta y el mensaje de error
printStackTrace() imprime la secuencia de llamadas al método que han producido la
excepción en el flujo de error tradicional
A continuación, mostramos un ejemplo
public class T10Exception {
int addInputs(String[] args) {
int sum = 0;
try {
for (int i=0; i<args.length; i++)
sum += Integer.parseInt(args[i]);
}
catch (NumberFormatException e) {
System.out.println("\nResultado de getMessage() " + e.getMessage());
System.out.println("Resultado de toString() " + e.toString());
System.out.println("Resultado de printStackTrace() " + e.printStackTrace();
}
return sum;
}
public static void main(String[] args) {
T10Exception self = new T10Exception();
String[] test = {"1", "2", "X"};
self.addInputs(test);
}
}
Éstos son los datos de entrada y salida
Salida de getMessage(): X
Salida de toString(): java.lang.NumberFormatException: X
Salida de printStackTrace():
java.lang.NumberFormatException: X
en java.lang.Integer.parseInt(Integer.java:414)
en java.lang.Integer.parseInt(Integer.java:463)
en T10Exception.addInputs(T10Exception.java:6)
en T10Exception.main(T10Exception.java:19)
En el ejemplo anterior, cuando el usuario introduce un valor no integer, el método
parseInt arroja una excepción NumberFormatException detectada por la cláusula
catch y el programa imprime el contenido de la excepción en distintos formatos.
Observe que printStackTrace() no devuelve una cadena. Imprime directamente el
mensaje en stderr.
Tal como vimos en el material de clase, las excepciones pueden heredar información de
unas a otras. Por ejemplo, FileNotFoundException amplía IOException de tal modo que
una cláusula catch (IOException e) también detectará la excepción
FileNotFoundException. Si no está seguro de qué excepción generará el segmento de
código, simplemente detecte (Exception e) y se detectará cualquier otra excepción.
Detectar varias excepciones
Es posible detectar varios tipos de excepciones en un bloque try…catch: simplemente
utilice una cláusula catch independiente para cada tipo, tal como se muestra a
continuación:
try { código }
catch (IOException e1)
{ e1.printStackTrace(); }
catch (NumberFormatException e2)
{ e2.printStackTrace(); }
Crear sus propias excepciones
Al igual que ocurre con otras clases de Java, puede ampliar las clases de
excepciones existentes y crear sus propios tipos. A continuación puede ver un
ejemplo
Class MyException extends NumberFormatException {
public MyException(String msg) {
super("Formato no válido " + msg);
}
}
Arrojar una excepción
En el ejemplo anterior, hemos detectado la excepción NumberFormatException y la
hemos gestionado in situ. Es posible que en algunas ocasiones este comportamiento no
sea el más indicado. Por ejemplo, un programador está escribiendo un método para
que el resto de las clases lo utilicen y que podría desencadenar una excepción. Tal vez
quiera que el usuario de la clase decida cómo gestionar la excepción. En este caso,
necesitará "arrojar" la excepción, esto es, delegar la responsabilidad de la gestión en el
llamante. Se hace del siguiente modo.
o Decidir qué excepción causará el método
o Declarar la cláusula "throws" en el encabezado del método
o Gestionar la excepción en el llamante (try/catch)
Ésta es la modificación del ejemplo anterior
public class T10Exception {
int addInputs(String[] args) throws NumberFormatException {
int sum = 0;
for (int i=0; i<args.length; i++)
sum += Integer.parseInt(args[i]);
return sum;
}
public static void main(String[] args) {
T10Exception self = new T10Exception();
String[] test = {"1", "2", "X"};
try {
self.addInputs(test);
}
catch (NumberFormatException e) {
System.out.println("\nResultado de getMessage() " + e.getMessage());
System.out.println("Resultado de toString() " + e.toString());
System.out.println("Resultado de printStackTrace() ");
e.printStackTrace();
}
}
}
En este caso, el método addInputs decide no gestionar la excepción. En su lugar, la
arroja al llamante. Por tanto, el método main debe detectarla y gestionarla. El
resultado será el mismo.
Observe que un método puede declarar excepciones no comprobadas que él mismo
arroja, pero DEBE declarar las excepciones comprobadas o, de lo contrario, el
compilador se quejará. NumberFormatException es un buen ejemplo de una excepción
sin comprobar que QUEREMOS comprobar. IOException o FileNotFoundException son un
buen ejemplo de excepciones comprobadas que se deben declarar.
Flujos
Hasta ahora, nuestros programas han recibido información introducida por el usuario a
través del teclado, por ejemplo, getText() de JTextField. En esta sección, le
mostraremos cómo utilizar los flujos para introducir datos y obtener información en
otras fuentes, como un archivo o una conexión de red.
Entrada, salida y error tradicionales
En realidad, ya ha utilizado los flujos para enviar datos a la pantalla desde el principio
del curso
o System.out.println(String) imprime una cadena en el flujo de salida
tradicional que, normalmente (auque no obligatoriamente), es la
"pantalla".
o Otro objeto de flujo de salida tradicional es el objeto System.err. Esta
objeto permite que un programa emita mensajes de error. En este caso,
de nuevo el resultado suele dirigirse por defecto a la pantalla.
System.out y System.err, así como System.in (que no hemos utilizado demasiado)
se crean automáticamente al ejecutarse un programa de Java. Estos objetos
podrían ser suficiente si sólo quiere escribir en la pantalla o leer desde el
teclado.
Flujos
La biblioteca java.io permite introducir y obtener datos de otras fuentes de datos,
como discos, conductos interprocesales o conexiones de red. Esto se logra gracias a los
flujos. Java proporciona cuatro tipos de flujos
o InputStream es un objeto desde el que se lee una secuencia de datos binarios
o Outputstream es un objeto en el que se escribe una secuencia de datos binarios
o Reader es un objeto en el que se lee una secuencia de texto
o Writer es un objeto en el que se escribe una secuencia de texto
Cada flujo tiene un número determinado de subclases y cada una de ellas gestiona un
tipo de fuente de datos. Por ejemplo:
o InputStream
o OutStream
o FileInputStream
o ObjectInputStream
o PipedInputStream
o FileOutputStream
o ObejctOutputStream
o PipedOutputStream
Una vez conectado un InputStream a una fuente de datos, pude utilizar su función
read() para leer los datos de dicha fuente. Sin embargo, la función read() es bastante
limitada: solamente puede leer arrays de bytes. La mayor parte del tiempo, necesitará
añadir un "filtro" para convertir los bytes en tipos de datos más útiles. Entre los
ejemplos de flujos de entrada de filtros se encuentran DataInputStream,
BufferedInputStream, etc.
En resumen, para leer datos de una fuente de datos, necesita seguir estos
procedimientos:
Identificar la fuente de datos (¿qué es? ¿qué tipos de datos contiene? etc.)
1.
2. Conectar un flujo de entrada adecuado a dicha fuente de datos (por ejemplo,
FileInputStream o ObjectInputStream)
3. Asociar un flujo del filtro a dicho flujo de entrada (p.e
Comentarios de: Clase adicional 10 (0)
No hay comentarios