IBM - Core Java - Libro 2

Core Java Código del Curso: CY420 Versión: 5.1 Guía del Estudiante Libro 2: Core Java IBM Training Worldwide Certifie

Views 50 Downloads 3 File size 2MB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Core Java Código del Curso: CY420 Versión: 5.1

Guía del Estudiante

Libro 2: Core Java

IBM Training Worldwide Certified Material

Información Sobre la Publicación Esta publicación ha sido producida usando Microsoft Word 2000 y Microsoft PowerPoint 2000 para Windows. Marcas Registradas IBM ® es una marca registrada por International Business Machines Corporation. Otras compañías, productos, y nombre de servicios pueden ser marcas registradas o marcas de servicios de otros. Marcas Registradas de otras Compañías HotJava browser, Java Development Kit (JDK), Java, Java Servlet, Solaris, Enterprise Java Beans, Java Server Pages, JDK, JSP – Sun Microsystems, Microsoft MAKECAB, Windows operating system, ASP, VB, .NET, VC++, Microsoft Access, Microsoft SQL Server, Microsoft ODBC for Oracle – Microsoft Corp, WinZip – Nico Mak Computing, Inc., Time – Time Warner, JDBC – Javasoft, Oracle – Oracle Corporation, Sybase – Sybase Inc., UDB DB2 – IBM. Edición Octubre 2007 La información contenida en este documento no ha sido sometida a ninguna prueba formal de IBM y es distribuida básicamente “como es" sin ninguna garantía ya sea expresa o implícita. El uso de esta información o la implementación de cualquiera de estas técnicas es responsabilidad del comprador y dependerá de la habilidad de éste para su evaluación e integración en el ambiente operacional del comprador. A pesar de que cada tema ha sido revisado por IBM para su exactitud en una situación específica, no hay garantía de que obtener el mismo resultado o uno similar a éste en otra situación. Los compradores que intenten adaptar estas técnicas a sus propios ambientes lo hacen bajo su propio riesgo. Copyright International Business Machines Corporation, 2007. All rights reserved. Este documento no puede ser reproducido en su totalidad o en parte sin el previo permiso escrito de IBM. Instrucciones Especiales para la Impresión de este Curso: No elimine páginas en blanco que puedan aparecer al final de cada unidad o entre unidades. Estas páginas fueron insertadas intencionalmente.

.

Guía del Estudiante

Core Java

Contenido Volumen 3: Manejo de Excepciones .................................................................1 Unidad 1: Manejo de Excepciones y Tipos de Excepciones...........................3 Objetivos de Aprendizaje

3

1. Introducción

4

2. Técnicas Tradicionales de Manejo de Errores

4

3. Excepciones y Condiciones Anormales

5

4. Java y el Manejo de Excepciones

5

5. Agrupar Excepciones en Java

14

6. Excepciones Verificadas y No Verificadas

17

7. La Clase Throwable y sus Clases Derivadas

17

8. Manejo de Excepciones

19

9. Flujo de Manejo de Excepciones

21

Resumen

23

Unidad 1: Examen de Autoevaluación

24

Respuestas a la Unidad 1: Examen de Autoevaluación

27

Unidad 2: Lanzamiento y Manejo de Excepciones ........................................29 Objetivos de Aprendizaje

29

1. Introducción

30

2. Excepciones Estándar en Java

30

3. Usar la Jerarquía de Excepciones

32

4. La Cláusula finally Revisada

34

5. Sobrescribir Métodos que Lanzan Excepciones

36

6. Crear Excepciones Definidas por el Usuario

39

7. Más de Excepciones Definidas por el Usuario

42

8. La Cláusula throws Revisada

45

Resumen

50

Unidad 2: Examen de Autoevaluación

51

Respuestas a la Unidad 2: Examen de Autoevaluación

53

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones ..............55 Objetivos de Aprendizaje

55

Ejercicios de Laboratorio

56

Volumen 4: Facilidades de Entrada / Salida ...................................................56 Unidad 1: Archivos y Flujos.............................................................................56 i © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Objetivos de Aprendizaje

56

1. Introducción

56

2. Archivos

56

3. Flujos

56

4. La Clase InputStream

56

5. La Clase OutputStream

56

6. La Clase Reader

56

7. La Clase Writer

56

8. La Clase Scanner

56

Resumen

56

Unidad 1: Examen de Autoevaluación

56

Respuestas a la Unidad 1: Examen de Autoevaluación

56

Unidad 2: Laboratorio de Archivos y Flujos...................................................56 Objetivos del Aprendizaje

56

Ejercicios de Laboratorio

56

Unidad 3: Serialización de Objetos .................................................................56 Objetivos del Aprendizaje

56

1. Introducción

56

2. Serialización de Objetos

56

3. Aplicaciones de la Serialización de Objetos

56

4. Implementando Serialización en Java

56

Resumen

56

Unidad 3: Examen de Autoevaluación

56

Respuestas a la Unidad 3: Examen de Autoevaluación

56

Unidad 4: Laboratorio de Serialización de Objetos .......................................56 Objetivos del Aprendizaje

56

Ejercicios de Laboratorio

56

ii © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Volumen 3: Manejo de Excepciones

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 1 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones Objetivos de Aprendizaje Al final de esta unidad, usted será capaz de: •

Definir las excepciones y explicar las técnicas tradicionales de manejo de errores.



Describir el manejo de excepciones en Java.



Diferenciar entre excepciones verificadas y no verificadas.



Describir las sub-clases de la clase Throwable.



Describir el flujo de manejo de excepciones en Java.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 3 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

1. Introducción En el Volumen 2 – Programación Orientada a Objetos, se revisó Java como lenguaje de programación y se identificaron los conceptos de clases, objetos, modificadores de acceso, herencia en java, interfaces y paquetes. En esta unidad, se discutirá como se manejan los errores en un programa. Los programas no están siempre libres de errores, en Java cuando ocurre una condición de error, se lanza una excepción. Las excepciones son eventos anormales que ocurren durante el curso de la ejecución de un programa y rompen la secuencia normal de ejecución del programa. Algunas de las preguntas inherentes a las excepciones, que le pueden surgir al programador son las siguientes: •

¿Necesariamente un programa debe manejar eventos anormales?



¿El código para el manejo de errores debe asociarse con cuál parte del programa?



¿Cómo se detecta y maneja el error durante el tiempo de ejecución?



¿Qué le pasa a la aplicación cuando se maneja un error?



¿Proveen los lenguajes de programación soporte para encontrar y manejar errores?

Muchas de estas preguntas serán respondidas en esta y la próxima unidad. Para empezar se discuten las técnicas tradicionales para el manejo de errores.

2. Técnicas Tradicionales de Manejo de Errores En los inicios de la programación de computadoras, lenguajes como Pascal, Fortran y C no proveían ningún soporte a los programadores para el manejo de errores. Era responsabilidad del programador proveer rutinas para el manejo de errores, debido a esto, muchos errores importantes no eran detectados en las aplicaciones. Todo esto se dedujo, porque el código para el manejo del error estaba escrito junto con el programa principal, esto hacía difícil distinguir el flujo del programa principal del código para manejo de errores. Adicionalmente, esta situación complicaba el proceso de depuración del programa. Lenguajes de programación desarrollados posteriormente como BASIC y COBOL proveían un soporte estructurado para la revisión y manejo de errores. Proporcionaban la siguiente construcción del lenguaje para el manejo de errores: ON ERROR GOTO ... Esta construcción separaba el código para el manejo del error del código principal. Cuando un programa encontraba un error, el control del programa saltaba a la posición especificada por el GOTO. La posición especificada contenía el código para el manejo Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 4

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

del error. Lenguajes de programación diferentes proveían sintaxis diferentes para la detección y manejo de errores. Sin embargo, la estructura básica era similar a la mencionada anteriormente. Aunque el código para manejo de errores con un lenguaje que lo soportara era mejor que ningún soporte, el código del programa principal todavía se intercalaba con el código para la verificación y manejo de errores. Además, el flujo de ejecución era interrumpido ya que el control saltaba a una posición diferente para luego retornar después de manejado el error. Con la evolución de la programación orientada a objetos, se introdujo una nueva forma de manejar los errores, en la cual, el código para el manejo del error era separado del código del programa principal.

3. Excepciones y Condiciones Anormales Como se mencionó anteriormente, las excepciones son eventos anormales que ocurren durante la ejecución del programa. Los siguientes son algunos ejemplos de cuando se lanzan excepciones: •

Cuando un número es dividido entre cero. Esto puede ser detectado sólo en tiempo de ejecución, ya que las operaciones se efectúan durante la ejecución del programa.



Cuando se accede a un elemento de un arreglo que esta fuera del límite del arreglo.



Cuando ocurre una condición de desborde (overflow o underflow) durante la asignación de valores a variables numéricas.



Cuando un recurso que es requerido por la aplicación no está disponible. Una aplicación, por ejemplo, puede requerir una impresora y la impresora puede no estar conectada a la computadora.



Cuando un programa requiere un archivo para lectura, y el archivo no está disponible en el sistema de archivos.



Cuando un programa accede a recursos del sistema sin autorización.

Estos son solo algunos ejemplos de cuando puede ocurrir una excepción en un programa. Algunas de estas no son lo suficientemente serias y la ejecución del programa puede continuar, una vez manejadas, pero hay excepciones que no permiten que continúe la ejecución del programa. A continuación se discute el soporte provisto por Java para el manejo de excepciones.

4. Java y el Manejo de Excepciones Java tiene incorporado la capacidad para asegurar que las excepciones son manejadas dentro del programa. Aunque los programadores pueden manejar algunos errores, otros son manejados por la JVM. El programador debe manejar un error como el de ‘archivo no encontrado’, mientras que el error ‘fuera de memoria’ será manejado por la JVM. La

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 5 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Figura 1.1 muestra la secuencia de acciones que ocurren cuando se presenta una condición anormal.

Figura 1.1: Secuencia de Acciones Cuando se Produce una Excepción

Se discute a continuación lo que significa arrojar una excepción.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 6

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

En Java, cuando ocurre un error, éste se encuentra en un método. El método crea un objeto de la excepción que ocurrió, para manejar el error, y separar el manejo del error del código actual. Así, si el método estaba efectuando algún cálculo matemático, si la variable no puede tomar un valor negativo, un objeto de la excepción que puede manejar esta excepción será creado. En Java, todas las clases excepción son derivadas de la clase base Exception. Una vez creado el objeto excepción, el método pasa el objeto excepción al sistema de tiempo de ejecución Java, este pase del objeto se hace a través del concepto de lanzar la excepción. El sistema de tiempo de ejecución busca en la pila de llamadas y ubica el método que manejará la excepción levantada. La pila de llamadas tendrá detalles de cómo se llamó al método que originó la excepción. En el caso de que el método más interno lance un error y no lo maneje, la excepción será pasada en forma ascendente por la pila de llamadas hasta que se consiga un método que maneje la excepción. Si se consigue este método, la excepción es manejada, sino la ejecución del programa se detiene. Java brinda soporte al manejo de excepciones con el uso de cinco palabras claves, que son: try, catch, throw, throws y finally. Se explican cada una de ellas en las siguientes secciones.

4.1 Usando Bloques try y catch Java provee dos cláusulas para el manejo de excepciones en una forma sofisticada. Se pueden manejar las excepciones en un programa Java, usando las cláusulas try y catch. Se usarán los términos bloques y cláusulas indistintamente, cuando se haga referencia a try, catch y finally (este último tratado en una sección posterior). A continuación se presenta un ejemplo para apreciar la importancia de separar la revisión y manejo del error del código principal. Ejemplo 1.1 Asuma que se quiere obtener el n-ésimo elemento de una lista de elementos diferentes si este es un string. El algoritmo es el siguiente: El algoritmo comienza aquí… 1. recuperarNEsimoElemento() { 2. aceptar lista; 3. obtener n-esimo elemento de la lista; 4. 5. }

retornar el elemento si es un String o retornar nulo;

El algoritmo termina aquí El algoritmo anterior no incluye nada para la verificación y manejo de errores. Se tienen cuatro eventos de revisión de error que puede proveer la función anterior: Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 7 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Si la lista es null. Si la lista esta disponible, pero vacía. Si el valor de 'N' no es un índice válido en la lista. Si el elemento N no es un string. Ahora se expande el algoritmo anterior para incluir el manejo de errores. El algoritmo comienza aquí… 1. String recuperarNEsimoElemento(List lista, int n) { 2. 3. 4.

String str;

5. 6. 7.

str = "Lista nula"; else if (esVacio(lista)) str = "Lista vacia";

8. 9. 10.

else if (n < 0 || n > numeroDeElementos(lista)) str = "Indice invalido"; else {

if (lista == null)

11. 12. 13.

str = getElemento(lista, n); if (!esString(str)) str = "No es un String";

14. 15. 16. 17.

} return str; }

El algoritmo termina aquí Se ha intercalado el código principal con el código para manejo de errores, haciéndolo difícil de entender. Se va a ver como manejar los errores anteriores en Java. El código Java comienza aquí… 1. // Definicion de Metodo en Java 2. String recuperarNEsimoElemento(List lista, int n) { 3. try { 4. 1) Obtener n-esimo elemento de la lista; 5. 6.

2) Retornar el elemento si es un String o retornar null; } catch (lista_es_nula) {

7. 8.

1) Manejo de la excepcion cuando la lista es nula; } catch (lista_esta_vacia) {

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 8

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

9. 10. 11.

1) Manejo de la excepcion cuando la lista esta vacia; } catch (indice_invalido) { 1) Manejo de la excepcion cuando el indice es invalido;

12. 13. 14.

} catch (elemento_no_es_String) { 1) Manejo de la excepcion cuando el elemento a recuperar no es un String;

15. 16. }

}

El código Java termina aquí En el código anterior, se nota que el código para manejo de errores está separado del código principal, que se concentra en la funcionalidad del método. El código que puede generar una excepción se coloca dentro del bloque try, y el código para el manejo del error se coloca dentro del bloque catch apropiado. Aunque, el algoritmo anterior es muy elegante, se debe recordar que el programador tiene que escribir el código para manejar la excepción. Fin del Ejemplo 1.1 Se mostrará ahora el uso de la cláusula throws en Java.

4.2 Usando la Cláusula throws La cláusula throws se usa cuando un método que lanza una excepción no maneja la excepción. Asuma que el método recuperarNEsimoElemento() no maneja ninguna excepción y que es invocado por el método validarLista(), entonces recuperarNEsimoElemento() debe especificar las excepciones que lanza, usando la cláusula throws, como a continuación: public String recuperarNEsimoElemento(List lista, int n) throws Excepcion1, Excepcion2, Excepcion3, Excepcion4 { // Obtiene el n-esimo elemento de la lista; // Retorna elemento si es String o retorna null; } Un método puede lanzar una o más excepciones. Todavía no se ha mostrado como se lanzan las excepciones, se explica en la Sección 4.3 – La Sentencia throw. Debido a que el método recuperarNEsimoElemento() no maneja las excepciones, debe usar la palabra reservada throws en su encabezado de método. Todas las excepciones verificadas lanzadas deben ser especificadas en el encabezado del método, los nombres usados en el ejemplo anterior son los nombres de las clases excepción creadas para manejar las diferentes excepciones. El método validarLista() será como a continuación se muestra: public void validarLista(List lista, int n) { Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 9 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

try { recuperarNEsimoElemento(lista, n); // Otras sentencias } catch (lista_es_nula) { // Manejo de la excepcion cuando la lista es nula; } catch (lista_esta_vacia) { // Manejo de la excepcion cuando la lista esta vacia; } catch (indice_invalido) { // Manejo de la excepcion cuando el indice es invalido; } catch (elemento_no_es_String) { // Manejo de la excepcion cuando el elemento a // recuperar no es un String; } } Se puede ver del código anterior que el bloque try-catch se uso en el método validarLista() en lugar de en el método recuperarNEsimoElemento(). Si validarLista() no maneja la excepción, necesita especificar usando la cláusula throws las excepciones que no maneja. Finalmente, las excepciones deben ser manejadas en algún punto del programa, dentro de la pila de llamadas. Si ningún manejador esta disponible la JVM maneja la excepción, y finaliza. Se explicó como manejar excepciones usando los bloques try y catch, además de como el método que lanza una excepción, lo indica, usando la cláusula throws. A continuación se explica como se puede lanzar una excepción.

4.3 La Sentencia throw La cláusula throws se usa para indicar cual método puede lanzar una excepción. Cuando ocurre un error en un programa, justo en el punto donde ocurre, una excepción es levantada, esto se hace usando la sentencia throw en Java. Observe el algoritmo anterior para entender como usar la sentencia throw para lanzar la excepción. El algoritmo comienza aquí… tipoDeRetorno nombreMetodo(tipoDeDato nombreArgumento) throws NombreExcepcion { // Declaraciones // Algunas sentencias if (algunaCondicion) throw new NombreExcepcion(); Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 10

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

else { // Continuar } } El algoritmo termina aquí En el algoritmo anterior, cuando algunaCondicion es verdadera, se lanza una excepción usando la sentencia throw. La sentencia throw lanza un objeto de la clase excepción NombreExcepcion. Este objeto debe pertenecer a la clase excepción especificada en la cláusula throws. En el ejemplo anterior, la sentencia throw crea un objeto de la clase NombreExcepcion y lo lanza. A menos que una excepción sea arrojada en el programa, no puede ser tomada o manejada en ningún lugar. Un método puede lanzar más de una excepción de la siguiente manera: El algoritmo comienza aquí… tipoDeRetorno nombreMetodo(tipoDeDato nombreArgumento) throws NombreExcepcion1, NombreExcepcion2 { // Declaraciones // Algunas sentencias if (algunaCondicion1) throw new NombreExcepcion1(); else { // Continuar if (algunaCondicion2) throw new NombreExcepcion2(); else // Continuar } } El algoritmo termina aquí En el algoritmo anterior, el método lanza dos excepciones mediante el uso de dos sentencias throw en el cuerpo del método. Si alguno de los métodos en una clase lanza un objeto excepción que no concuerda con las clases excepción especificadas en la cláusula throws del método, se genera un error en tiempo de compilación. El método recuperarNEsimoElemento() usado anteriormente se muestra ahora con las sentencias throw incluidas:

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 11 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

El código Java comienza aquí… public String recuperarNEsimoElemento(List lista, int n) throws ListaNullExcepcion, ListaVaciaExcepcion, IndiceInvalidoExcepcion, ElementoNoEsStringExcepcion { String elemento = null; if (lista == null) throw new ListaNullExcepcion(); if (esVacio(lista)) throw new ListaVaciaExcepcion(); if (n < 0 || n > numeroDeElementos(lista)) throw new IndiceInvalidoExcepcion(); elemento = getElemento(lista, n); if (!esString(elemento)) throw new ElementoNoEsStringExcepcion(); return elemento; } El código Java termina aquí En el código anterior, se ve como el método lanza cuatro excepciones explícitamente usando la sentencia throw. Si el método que invoca al método anterior no maneja las excepciones, entonces solamente debe especificar la cláusula throws en su declaración de método. Solo la clase que levanta la excepción usa la sentencia throw. A continuación se explicará el uso de la cláusula finally en los programas.

4.4 Usando el Bloque finally Se vio que en el bloque try-catch, el bloque try contiene el código que puede generar la excepción, y el bloque catch captura las excepciones indicadas lanzadas por el bloque de código y las maneja. Existe otro tipo de bloque, llamado bloque finally, que puede ser añadido al final de todos los bloques catch. Se usa básicamente para tareas de limpieza, como cerrar archivos y liberar recursos.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 12

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

El bloque finally se ejecuta después de la ejecución de todos los bloques catch. El bloque finally siempre se ejecuta aún cuando no se lance ninguna excepción en el bloque try o aunque los bloques try-catch tengan una sentencia return. El siguiente algoritmo muestra la estructura general del bloque try-catch-finally: El algoritmo comienza aquí… try{ // Código que puede generar las execpciones } catch (ChequeoExcepcion1 x1) { // Código para manejo de la excepción } catch (ChequeoExcepcion2 x2) { // Código para manejo de la excepción } finally(){ // Código de limpieza } El algoritmo termina aquí La Figura 1.2 explica el uso del bloque finally.

Figura 1.2: Uso del Bloque finally

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 13 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

La Figura 1.2 muestra dos escenarios en los cuales se invoca el código en el bloque finally. Se explica a continuación cada uno de ellos. En el primer escenario, el método lanza todas las excepciones, ya que no hay un bloque catch. El bloque finally es ejecutado siempre. Aquí, la organización esta garantizada, al quedar separado el manejo de excepciones. El segundo escenario muestra sentencias catch además del bloque finally. El método captura las excepciones que coincidan con las del bloque catch. El bloque catch lanza una nueva excepción. La pulcritud esta todavía garantizada. Java también permite a los programadores crear sus propias excepciones. Esto les ayuda a manejar situaciones de error que podrían surgir de acuerdo al comportamiento de los objetos de las clases escritas por ellos. Se discutirá en detalle esta característica poderosa en la Unidad 2- Lanzamiento y Manejo de Excepciones. A continuación se explica como se pueden agrupar las excepciones.

5. Agrupar Excepciones en Java Varias excepciones pueden ocurrir en un programa Java. Clasificar las excepciones las hacen más fáciles de manejar. Las excepciones que denotan desborde del tipo (overflow y underflow) en enteros y la división de un número entre cero, pueden ser clasificadas en una categoría. Las excepciones relacionadas con la manipulación de arreglos, como índice fuera de límites o elemento no presente pueden ser agrupadas en otra categoría. Las excepciones relacionadas con las pilas como pila vacía o pila llena pueden ser agrupadas separadamente, y también las excepciones que se ocupan de la lectura o escritura en archivos pueden ser agrupadas aparte. Es posible clasificar las excepciones, debido a que Java soporta la herencia. Se puede tener una superclase que especifique las características comunes a todas las excepciones de un tipo en particular. Todas las excepciones bajo una misma categoría pueden heredar de esta super clase. Todos los tipos de excepciones y errores en Java son sub-clases de la clase Throwable o una de las sub-clases de la clase Throwable. La Figura 1.3 representa la agrupación de las excepciones relacionadas con pilas. En la representación jerárquica de las clases excepción, los nodos hoja denotan tipos específicos de excepciones y errores, además los nodos intermedios denotan una categoría general de la excepción.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 14

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

En la Figura 1.3, PilaVaciaExcepcion y PilaLlenaExcepcion denotan dos tipos específicos de excepciones de pila. La PilaExcepcion representa la categoría general de las excepciones de pila.

Figura 1.3: Jerarquía Hipotética de las Excepciones de Pila

La Figura 1.4 representa los errores que ocurren en la lectura y escritura de archivos.

Figura 1.4: Jerarquía Hipotética de la Excepciones de la Clase File

Nota: Las excepciones en las sub-clases deben ser manejadas antes que las excepciones en las superclases. Si las superclases son manejadas primero, el código que maneja las subclases nunca alcanzará las excepciones en la subclase. Aunque es útil clasificar las excepciones en categorías y manejar una categoría particular de excepciones, algunas veces la situación puede demandar que cada excepción se maneje separadamente. Por esto, hay dos formas en las que se puede capturar y manejar excepciones. El primer método es capturar cada excepción separadamente, comenzando desde el nodo

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 15 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

inferior y subiendo en la jerarquía. El segundo método es capturar directamente la excepción representada por el nodo superior. El algoritmo para el primer método de captura de excepciones, es decir, capturar cada excepción separadamente, es como se muestra a continuación:

El algoritmo comienza aquí… try{ // Código que puede generar la excepción } catch (FileNotFoundException x1) { //Código para manejar la excepción } catch (FileCorruptException x2) { // Código para manejar la excepción } catch (NoPermissionOnFileException x3) { // Código para manejar la excepción } catch (CannotReadException x4) { // Código para manejar la excepción } catch (FileException x5) { // Código para manejar la excepción } El algoritmo termina aquí En el código anterior, si la primera sentencia catch capturara FileException, entonces todas las excepciones lanzadas, que sean sub-clases de FileException serán capturadas justo en el primer catch. Esto no es deseable normalmente, ya que se quiere que cada excepción específica sea manejada separadamente. Por esto, se tiene a la superclase FileException como el último manejador de excepción. El segundo método de capturar excepciones, es decir, capturar la expresión del nodo superior directamente, es como a continuación se muestra: El algoritmo comienza aquí… try{ // Código que puede generar la excepción Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 16

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

} catch (FileException x) {/* // Código para manejar la excepción } El algoritmo termina aquí Una vez entendidos los conceptos de excepciones, se explican ahora las excepciones verificadas y las no verificadas.

6. Excepciones Verificadas y No Verificadas Las excepciones verificadas son aquellas que el programador debe capturar y manejar dentro de la aplicación. Si el programador no captura una excepción verificada, o no la especifica usando la cláusula throws en la declaración del método, se producirá un error en tiempo de compilación. El programa no compilará hasta que la excepción sea capturada y manejada en algún punto apropiado dentro del programa. Las excepciones no verificadas son excepciones del tiempo de ejecución, las cuales son detectadas por la JVM. Las excepciones no verificadas son las excepciones de la clase RuntimeException y sus subclases que son lanzadas en un programa Java cuando hay un problema en la JVM. A los programadores no se les exige capturar y manejar las excepciones no verificadas. Existen situaciones donde se sabe que el código Java que se escribe puede arrojar excepciones, pero no se está seguro del tipo de la excepción que será lanzada. En estos casos, se puede simplemente capturarlas usando la clase Exception, que es la superclase de las excepciones, y una sub-clase de la clase Throwable. No es necesario capturar cada excepción separadamente. Java provee varias clases para manejar excepciones y errores. Se presentan a continuación.

7. La Clase Throwable y sus Clases Derivadas La Figura 1.5 muestra la jerarquía de clases general de varias excepciones y errores provistos en la librería de Java. La clase Throwable es la superclase de las clases Error y Exception.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 17 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Figura 1.5: Jerarquía General de Clases de Excepciones y Errores de la Librería de Java

Los objetos de las clases Error y Exception son las excepciones lanzadas en los programas Java. Los errores causan que los objetos Error sean lanzados y las excepciones causan que los objetos Exception sean lanzados. Los errores son excepciones de bajo nivel, lanzados por la JVM. Java provee pocas clases excepción como parte de su librería, se explican ahora brevemente. Los programas Java que se escriben pueden lanzar y capturar solo excepciones, y no errores. La clase RuntimeException es un tipo especial de excepción que indica las excepciones ocurridas en la JVM en tiempo de ejecución. La clase NullPointerException es un tipo de RuntimeException que ocurre cuando un método intenta acceder a un objeto a través de una referencia a null. No es necesario para los programadores capturar y manejar excepciones del tiempo de ejecución, ya que es difícil seguirlas y capturarlas. Se ha discutido acerca de las excepciones, ahora Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 18

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

pasando a los errores, algunos ejemplos de errores son: errores de AWT, errores de enlace, error de hilo muerto, y error de la máquina virtual. Java tiene clases separadas para manejar todos estos tipos de errores. AWT (Abstract Window Toolkit) será cubierto en el Volumen 5, Unidad 1 – Componentes y Contenedores AWT. A continuación se resumen las posibles acciones que se pueden tomar cuando se encuentra una excepción en el programa.

8. Manejo de Excepciones Los programadores pueden manejar las excepciones en cuatro formas, que son: •

Ignorar las excepciones no verificadas.



Manejar las excepciones con un bloque try-catch.



Lanzar las excepciones al método que invocó al actual.



Manejar las excepciones y relanzarlas al método que invocó al actual.

8.1 Ignorar las Excepciones No Verificadas Los programadores pueden o no manejar las excepciones no verificadas. El compilador no impone ninguna restricción en las excepciones no verificadas. Los programadores pueden ignorarlas. La Figura 1.6 muestra como las excepciones no verificadas pueden ser ignoradas.

Figura 1.6: Ignorando las Excepciones No Verificadas

Si no se toma ninguna acción cuando ocurre una excepción no verificada, el método en el cual ocurre la excepción termina. La excepción es enviada al método que llamó al primer método. Esta es propagada hasta que la excepción sea manejada o el programa termina.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 19 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

8.2 Manejar Excepciones con el bloque try-catch Esta es una forma estándar de manejar excepciones en Java. El bloque try-catch intercepta la excepción y la maneja. La excepción potencial puede ocurrir en cualquier lugar dentro del bloque try. Una vez que la excepción ocurre, el control se transfiere al bloque catch para el manejo. La Figura 1.7 ilustra esto.

Figura 1.7: Manejando Excepciones con el Bloque try-catch

En la figura, se llama al método registrarEmpleado() dentro del bloque try. En caso de que se lance EmpleadoActualExcepcion, es manejada dentro del bloque catch. La dirección del objeto EmpleadoActualExcepcion es recibida dentro del bloque catch para el procesamiento.

8.3 Lanzar Excepciones al Método Invocante Puede haber situaciones donde se tendrá una excepción verificada, pero no se está seguro de que se tiene que hacer si la excepción es capturada. En estos casos, se puede pasar la excepción al método que llamó al método actual. Considere la Figura 1.8, donde el método registrarEmpleado() lanza EmpleadoActualExcepcion. En caso de que la excepción ocurra en este método, la excepción es manejada en el método que invocó al método registrarEmpleado().

Figure 1.8: Lanzando Excepciones al Método Invocante

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 20

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

8.4 Manejar Excepciones y Re-lanzarlas al Método Invocante Puede haber situaciones donde se quiera capturar una excepción, pero no se puede resolver la raíz de la causa del mismo. En estos casos, se puede capturar la excepción, hacer lo que se pueda para corregirla y pasar el objeto excepción al método invocante. Esto se muestra en la Figura 1.9.

Figura 1.9: Manejar y Relanzar Excepciones al Método Invocante

En el código anterior, si el objeto e es modificado dentro del bloque catch, y luego relanzado, el e modificado será lanzado. Así, un manejo parcial del error puede realizarse, donde el objeto e puede ser modificado, y luego relanzado. Se han visto varias formas de manejar excepciones y también diversos escenarios, donde se debe adoptar un método particular de manejo. Se puede decidir la forma apropiada de manejar excepciones, sin embargo, cuando hay numerosas invocaciones a métodos, manejo de excepciones y bloques que lanzan excepciones, el programador tiene que entender el flujo de las excepciones. Se discute a continuación el flujo de manejo de excepciones.

9. Flujo de Manejo de Excepciones Cuando se tienen muchas invocaciones a métodos y métodos lanzando las excepciones a los métodos que los invocaron, se torna difícil entender el flujo de la excepción. Considere la Figura 1.10, que explica el flujo de una excepción.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 21 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Figura 1.10: Flujo del Manejo de una Excepción

El método enemistar() es el detector de la condición de error. En el punto de la detección, crea y lanza un objeto. Un objeto, que es especificado por el 'throw', y debe ser una subclase de la clase Throwable. Asuma que algún método invoca al método cobrar(). Este a la vez llama al método prestar() dentro un bloque try-catch. La excepción lanzada por el método prestar() es manejada por el método cobrar() dado que no hay bloque catch definido en prestar(). El método prestar() invoca a enemistar(), que lanza la excepción X. Dado que la excepción en enemistar() no es manejada dentro de prestar()es relanzada al método cobrar().

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 22

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Resumen Ahora que ha completado esta unidad, usted debe ser capaz de: •

Definir las excepciones y las técnicas tradicionales para el manejo de errores.



Describir el manejo de excepciones en Java.



Diferenciar entre las excepciones verificadas y no verificadas.



Describir las sub-clases de la clase Throwable.



Describir el flujo de manejo de excepciones en Java.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 23 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Unidad 1: Examen de Autoevaluación 1) ¿Cuáles de las siguientes sentencias son verdaderas? a) Las excepciones son eventos. b) Los errores causan excepciones. c) Las excepciones causan errors. d) Todos los eventos son excepciones. 2) ¿Cuáles de las siguientes opciones pueden causar excepciones? a) Una falla de chip de memoria. b) Un intento de dividir un entero entre cero. c) Una referencia a una ubicación de memoria no asignada al usuario. d) Un intento de ejecutar una instrucción ilegal. 3) En Java, ¿cuáles de las siguientes opciones son consideradas como errores? a) Una falla de chip de memoria. b) Un intento de dividir un entero entre cero. c) Una referencia a una ubicación de memoria no asignada al usuario. d) Un intento de ejecutar una instrucción ilegal. 4) ¿Cuál de las siguientes es la clase base de todas las excepciones y errores? a) Exception. b) Error. c) Throwable. d) Ninguna de las anteriores. 5) En Java, tanto Error como Exception se derivan de la clase Throwable. a) Verdadero b) Falso 6) En Java, RuntimeException no necesita ser capturada ni manejada por el programador. a) Verdadero b) Falso

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 24

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

7) Si A es la superclase de B, C y D, donde A, B, C y D son clases excepción, ¿cuál es el mensaje impreso cuando una excepción de la clase B es lanzada cuando se invoca al method1. (Refiérase al fragmento de código dado a continuación para responder a esta pregunta.) try { // metodo1 invocado aqui } catch(Throwable t) { System.out.println("T"); } catch (A a) { System.out.println("A"); } catch (B b) { System.out.println("B"); } catch (Exception e) { System.out.println("E"); } a) B b) A c) Error de compilación d) E 8) Las sentencias en Java dentro del bloque finally siempre serán ejecutadas ya sea que una excepción sea lanzada o no. a) Verdadero b) Falso 9) ¿Qué pasaría si throw object; es especificado y object no es un objeto Throwable? a) El throw será válido. b) Será convertido en un objeto Throwable y la sentencia será ejecutada. c) El compilador señalaría un error. d) Esto lanzaría una excepción.

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 25 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

10) ¿Cuál palabra clave se usa para indicar que un método lanza una excepción? a)

throw.

b)

thrown.

c)

throws.

d)

Ninguna de las anteriores.

Unidad 1: Manejo de Excepciones y Tipos de Excepciones

Libro 2: Core Java 26

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Respuestas a la Unidad 1: Examen de Autoevaluación 1) a y b 2) b 3) a, c y d 4) c 5) a 6) a 7) c 8) a 9) c 10) c

Libro 2: Core Java

Unidad 1: Manejo de Excepciones y Tipos de Excepciones 27 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones Objetivos de Aprendizaje Al final de esta unidad, usted será capaz de: •

Mencionar las excepciones estándar en Java.



Describir el uso de la jerarquía de excepciones.



Explicar como sobrescribir métodos que lanzan excepciones.



Crear excepciones definidas por el usuario.

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 29 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

1. Introducción En la Unidad 1 – Manejo de Excepciones y Tipos de Excepciones, se explicaron las excepciones, la importancia de manejar excepciones y las clases excepción en Java. Se mostraron las sentencias básicas en Java try, catch y finally, que ayudan a manejar las excepciones y también se discutieron las excepciones verificadas y no verificadas. En esta unidad, se discutirán algunos ejemplos que ilustran el manejo de las excepciones de Java. También se explicará el método para definir, capturar y manejar excepciones definidas por el usuario. Igualmente se explicó que Java provee soporte para manejar excepciones en la forma de excepciones verificadas y no verificadas. Estas forman parte de la clasificación general de las excepciones estándar en Java. Java también le proporciona al programador la posibilidad de definir excepciones, que son llamadas excepciones definidas por el usuario. Antes, de proceder se explican las excepciones estándar en Java.

2. Excepciones Estándar en Java Se ha estudiado que las excepciones estándar son de dos tipos, verificadas y no verificadas. Las excepciones verificadas son aquellas que el programador debe capturar y manejar dentro de la aplicación, las excepciones verificadas no son del sistema de tiempo de ejecución. Si el programador no captura una excepción verificada usando el bloque try-catch, o no la especifica usando la cláusula throws en la declaración del método, se arrojará un error en tiempo de compilación. Si un código puede lanzar más de una excepción, entonces el código debe ser colocado dentro de un bloque try y seguido de un bloque catch para cada excepción que puede ser lanzada. Observe el siguiente ejemplo. Ejemplo 2.1 El programa de este ejemplo ilustra como cada excepción se maneja separadamente con diferentes bloques catch. El código Java comienza aquí… 1. /*Definicion de la clase ExcepcionEjemplo comienza aqui*/ 2. public class ExcepcionEjemplo { 3. /* Metodo main comienza aqui */ 4. public static void main(String[] args) { 5. 6. 7.

float miArregloFloat[] = new float[10]; int i;

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 30

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

8. 9. 10.

/* Chequear por argumento de línea de comando */ if (args.length == 0) System.out.println(

11. 12. 13.

"Uso invalido de ExcepcionEjemplo"); else { try {

14. 15. 16.

i = Integer.parseInt(args[0]); miArregloFloat[i - 1] = (float) 11.234; System.out.println(miArregloFloat[i]);

17. 18.

} catch (ArrayIndexOutOfBoundsException e) { System.out.println(

19. 20. 21.

"El valor del argumento no puede exceder de 10"); } catch (NumberFormatException e) { System.out.println(

22. 23. 24.

"El valor del argumento debe ser un numero entero"); } }

25. }/* Metodo main termina aqui */ 26. }/* Definicion de la clase ExcepcionEjemplo termina aqui */ El código Java termina aquí En este programa, primero se revisa si se tiene una entrada a través de la línea de comandos usando un simple if. Un mensaje de error se muestra cuando no se tiene entrada por la línea de comandos. Seguidamente, se tiene un bloque try que convierte el valor de entrada en un entero. Note que los argumentos de la línea de comandos son tomados como strings. El método parseInt() en Integer convierte el string "10" en el entero 10 si este valor es pasado como entrada en la línea de comandos. Luego, se usa el entero convertido como subíndice para el arreglo miArregloFloat, y un valor de punto flotante se le asigna al elemento i. Dos excepciones pueden ser lanzadas en el bloque try, las cuales son capturadas por los bloques catch que siguen al bloque try. Si la entrada no es un entero, se lanza una NumberFormatException, si el valor de la entrada excede el 10, se lanza una ArrayIndexOutOfBoundsException. Los mensajes que se reciben en cada caso, se muestran a continuación. Cuando el valor de la entrada no es un entero: El valor del argumento debe ser un numero entero Cuando el valor de la entrada excede el tamaño del arreglo: El valor del argumento no puede exceder de 10 Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 31 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

En este programa se pudo haber utilizado sola la superclase Exception en el bloque catch. El tener la superclase ayuda a capturar todas las excepciones lanzadas en el bloque try. Sin embargo, no se podrá manejar cada excepción separadamente. Fin del Ejemplo 2.1 A continuación se verá como usar la jerarquía de excepciones.

3. Usar la Jerarquía de Excepciones Un bloque try puede tener cualquier cantidad de manejadores catch. Cuando se lanza una excepción, el control pasa al manejador catch apropiado. Cuando los manejadores catch pertenecen a diferentes clases en una jerarquía de excepciones, se sabe que las subclases en la jerarquía de excepciones deben ser capturadas antes que las superclase en la jerarquía de excepciones. Si las excepciones de las superclases son tomadas antes que las excepciones de las subclases, el compilador generará un error. Esto, porque la superclase se refiere a un concepto de generalización, mientras que la subclase representa una especialización del mismo concepto. Así, los manejadores de excepciones deben siempre primero manejar las excepciones en las subclases de la jerarquía. A continuación se presenta un ejemplo. Ejemplo 2.2 El fragmento de código en el ejemplo ilustra el concepto de la jerarquía de excepciones que se ha discutido. El código Java comienza aquí… try { i = Integer.parseInt(args[0]); miArregloFloat[i - 1] = (float) 11.234; System.out.println(miArregloFloat[i]); }catch (Exception e) { System.out.println("Alguna excepcion ha sido capturada"); }catch (ArrayIndexOutOfBoundsException e) { System.out.println( "El valor del argumento no puede exceder de 10"); }catch (NumberFormatException e) { System.out.println( "El valor del argumento debe ser un numero entero"); } El código Java termina aquí Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 32

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Un error en tiempo de compilación se genera para el código anterior, porque ya se han provisto los manejadores catch para manejar excepciones específicas. En Java, no se permite que un manejador para una excepción de una superclase preceda a uno de una subclase. Sin embargo, se puede dejar que el manejador de la superclase sea el último manejador de excepciones. Esto lo muestra el siguiente código: El código Java comienza aquí… catch (ArrayIndexOutOfBoundsException e) { System.out.println( "El valor del argumento no puede exceder de 10"); }catch (NumberFormatException e) { System.out.println( "El valor del argumento debe ser un numero entero"); }catch (Exception e) { System.out.println( "Alguna excepcion ha sido capturada"); } El código Java termina aquí En el segmento de código anterior, si se lanza ArrayIndexOutOfBoundsException, el primer bloque catch la maneja. Si se lanza NumberFormatException, el segundo bloque catch la maneja, y si alguna otra excepción se lanza, es manejada por el tercer bloque catch. Fin del Ejemplo 2.2 Si no hay jerarquía de herencia entre las excepciones que pueden ser lanzadas en un programa, entonces las excepciones pueden ser capturadas en cualquier orden. La Figura 2.1 ilustra el manejo de excepciones usando un bloque try-catch. Los bloques catch se usan para capturar EOFException, FileNotFoundException, y ObjectStreamException. El orden en el cual estas excepciones son capturadas no importa, porque no hay jerarquía de herencia entre estas tres excepciones ya que todas son subclases de la clase java.io.IOException.

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 33 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Figura 2.1: Manejo de Múltiples Excepciones

Una vez tratado exhaustivamente las excepciones en Java, se discute brevemente la cláusula finally mencionada en la Unidad 1 – Manejo de Excepciones y Tipos de Excepciones. En la Unidad 1, se dijo que la cláusula finally se puede usar para manejar excepciones estándar. A continuación, se discute como esta cláusula puede ser usada también para manejar excepciones definidas por el usuario.

4. La Cláusula finally Revisada En la Unidad 1- Manejo de Excepciones y Tipos de Excepciones, mostró que el bloque finally se puede usar al final del bloque try-catch para realizar operaciones de limpieza. El bloque finally será ejecutado sin importar si la excepción es lanzada o no y aún si el bloque try-catch tiene una sentencia return. Sin embargo, no será ejecutado si se tiene la siguiente sentencia: System.exit(0); En cualquiera de los bloques try o catch System.exit(0) simplemente finalizará el programa, sin hacer ninguna operación de limpieza. Usar el bloque finally y la instrucción System.exit(0)juntos se considera una práctica pobre de programación, debido a que el control del programa nunca alcanzará el bloque finally. Se presenta a continuación un ejemplo para entenderlo mejor. Ejemplo 2.3 Se escribe un programa que calcula la división de dos enteros que son pasados como argumentos.

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 34

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

El código Java comienza aquí… 1. /*Definicion de la clase comienza aqui*/ 2. public class EnteroExcepcionEjemplo { 3. 4. 5.

/* Metodo main comienza aqui */ public static void main(String[] args) { System.out.println(

6. 7. 8.

"Invocando dividirEnteros " + "para dividir 12 entre 3"); dividirEnteros(12, 3);

9. 10. 11.

System.out.println( "Invocando dividirEnteros " + "para dividir 12 entre 0");

12. 13. 14.

dividirEnteros(12, 0); }/* Metodo main termina aqui */

15. 16. 17.

/* Metodo dividirEnteros comienza aqui */ public static void dividirEnteros(int x, int y) { try {

18. 19. 20.

int z = x / y; System.out.println("Cociente: " + z); }// Fin del bloque try

21. 22. 23.

catch (Exception e) { System.out.println( "Ocurrio una excepcion efectuando la division");

24. 25.

}// Fin del bloque Exception finally {

26. 27. 28.

System.out.println( "Ejecucion del bloque finally"); }// Fin del bloque finally

29. }/* Metodo dividirEnteros termina aqui */ 30. }/* Definicion de la clase termina aqui */ El código Java termina aquí La salida del código anterior será como sigue: Invocando dividirEnteros para dividir 12 entre 3 Cociente: 4 Ejecucion del bloque finally Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 35 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Invocando dividirEnteros para dividir 12 entre 0 Ocurrio una excepcion efectuando la division Ejecucion del bloque finally Fin del Ejemplo 2.3 En este ejemplo, cuando el método dividirEnteros es invocado (línea 8) por primera vez con los argumentos 12 y 3, el resultado de la operación es 4 y este valor es almacenado en z. La próxima instrucción es ejecutada y se imprime lo siguiente: Cociente: 4 Luego la cláusula finally se ejecuta, e imprime lo siguiente: Ejecucion del bloque finally Cuando el método dividirEnteros se ejecuta por segunda vez con argumentos 12 y 0(línea 12), se sabe que resultará en un error porque un entero se divide entre cero. En este caso se arroja una excepción, y por esto la próxima instrucción, System.out.println no se ejecuta. La excepción será capturada por el bloque catch y cuando la sentencia dentro del bloque catch se ejecuta, se imprime lo siguiente: Ocurrio una excepcion efectuando la division Luego, el bloque finally se ejecuta y se imprime lo siguiente: Ejecucion del bloque finally Los métodos que lanzan excepciones pueden también ser sobrescritos como los métodos normales en Java. Esta sobrescritura ayuda cuando las subclases proveen una funcionalidad específica para el método. A continuación se aprenderá como sobrescribir métodos que lanzan excepciones.

5. Sobrescribir Métodos que Lanzan Excepciones Cuando la superclase y su subclase tienen métodos con el mismo nombre, número, tipo de argumentos y orden, la subclase esta sobrescribiendo el método en la superclase. Por esto, cuando se invoca este método desde un objeto de la subclase, solo el método que fue declarado en la subclase será ejecutado. El método declarado en la superclase está oculto. Cuando una subclase sobrescribe un método que lanza una excepción declarada en su superclase, la subclase puede hacer una de las siguientes opciones en el método sobrescrito: •

El método en la subclase puede lanzar el mismo tipo de excepciones lanzadas en el método de la superclase.



El método en la subclase puede lanzar subclases de las excepciones lanzadas por el método en la superclase.

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 36

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Por ejemplo, asuma que la excepción A tiene las subclases B y C. Otra clase llamada Super en su método miMetodo lanza una excepción de tipo A. Cualquier clase derivada de Super, cuando sobrescriba miMetodo, puede lanzar una excepción de tipo A, o las subclases de A, que son B y C. Las subclases de Super no pueden lanzar ninguna otra excepción en el método miMetodo. El método en la subclase puede lanzar menos excepciones que el método en la superclase o puede no lanzar ninguna excepción. Sin embargo, el método declarado en la subclase no puede lanzar una excepción que sea superclase de la excepción lanzada en el método de la superclase. Se presenta el Ejemplo 2.4 para entender esto claramente. Nota: Estas reglas aplican solo para excepciones verificadas, y solo para métodos sobrescritos no sobrecargados. Ejemplo 2.4 El siguiente código ilustra el concepto de lanzar excepciones en superclase y subclases. El código Java comienza aquí… 1. 2. 3.

import javax.naming.LinkException; import javax.naming.NamingException;

4. 5. 6.

/*Definicion de la clase SuperClase comienza aqui*/ class SuperClase{ /* Metodo miMetodo comienza aqui */

7. 8. 9.

public static void miMetodo(int a) throws LinkException{

10. }/* Metodo miMetodo termina aqui */ 11. }/* Definicion de la clase SuperClase termina aqui */ 12. 13. /*Definicion de la clase SubClase comienza aqui*/ 14. public class SubClase extends SuperClase{ 15. /* Metodo miMetodo comienza aqui */ 16. 17.

public static void miMetodo(int a) throws NamingException{

18. 19. 20.

}/* Metodo miMetodo termina aqui */

21.

/* Metodo main comienza aqui */

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 37 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

22. 23. 24. 25. 26. 27.

Guía del Estudiante

public static void main(String[] args) { SubClase sc = new SubClase(); try { sc.miMetodo(10); }// Fin del bloque try catch (Exception e) {

28. }// Fin del bloque catch 29. }/* Metodo main termina aqui */ 30. }/* Definicion de la clase SubClase termina aqui */ El código Java termina aquí Este programa no compilará (línea 16 en SubClase) porque el método miMetodo en SuperClase lanza LinkException, y el método miMetodo en SubClase lanza NamingException, que es superclase de LinkException. Suponga que el método miMetodo en SuperClase lanza NamingException, y el de SubClase lanza LinkException, entonces el programa compilará. Vea las líneas que cambiarían en el ejemplo anterior: El código Java comienza aquí… . . 1. /*Definicion de la clase SuperClase comienza aqui*/ 2. class SuperClase{ 3. /* Metodo miMetodo comienza aqui */ 4. 5.

public static void miMetodo(int a) throws NamingException{

6. 7. }/* Metodo miMetodo termina aqui */ 8. }/* Definicion de la clase SuperClase termina aqui */ 9. 10. /*Definicion de la clase SubClase comienza aqui*/ 11. public class SubClase extends SuperClase{ 12. 13. 14.

/* Metodo miMetodo comienza aqui */ public static void miMetodo(int a) throws LinkException{

15. 16. .

}/* Metodo miMetodo termina aqui */

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 38

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

. El código Java termina aquí Asuma que el método miMetodo en SubClase no lanza ninguna excepción. Aún así, el programa compila, ya que el método sobrescrito puede lanzar menos número de excepciones o ninguna excepción. Esto se ilustra en el siguiente fragmento de código: El código Java comienza aquí… . . 1. /*Definicion de la clase SuperClase comienza aqui*/ 2. class SuperClase{ 3. /* Metodo miMetodo comienza aqui */ 4. public static void miMetodo(int a) 5. throws LinkException{ 6. 7.

}/* Metodo miMetodo termina aqui */

8. }/* Definicion de la clase SuperClase termina aqui */ 9. 10. /*Definicion de la clase SubClase comienza aqui*/ 11. public class SubClase extends SuperClase{ 12. /* Metodo miMetodo comienza aqui */ 13. 14. 15.

public static void miMetodo(int a){ }/* Metodo miMetodo termina aqui */

. . El código Java termina aquí En el programa anterior, aunque miMetodo(), definido en la clase SubClase, no lanza ninguna excepción, el programa compila. Fin del Ejemplo 2.4 Se discute a continuación como las excepciones definidas por el usuario pueden ser creadas para adaptarse a los programas.

6. Crear Excepciones Definidas por el Usuario Cuando se crean clases propias en Java, se elaboran excepciones propias o personalizadas para lanzar, capturar y manejar. Se pueden escribir clases de Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 39 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

excepciones propias para adaptar su comportamiento. En Java, las excepciones se pueden crear para adaptarlas a nuestras necesidades de programación. También es posible crear una jerarquía de excepciones. Para crear una excepción, primero se tiene que declarar una clase que sea subclase de la clase Exception. El constructor de la nueva clase excepción que se crea invoca al constructor de su superclase (la clase Exception). En la Figura 2.4, se ilustra que la clase MiExcepcion es la clase excepción que se crea, esta clase extiende de la clase Exception. El constructor de MiExcepcion solamente invoca al constructor de su superclase, la clase Exception.

public class MiExcepcion extends Exception { public MiExcepcion(String mensaje) { super(mensaje); } //Esto es, ahora tiene su propia excepcion. //Sin embargo, todavia falta un poco mas por hacer }

Figura 2.2: Creando Una Clase Excepción Definida por el Usuario

Se entiende mejor esto con un ejemplo. Ejemplo 2.5 El siguiente programa crea tres excepciones, son estas: MiBaseExcepcion, MiSubExcepcion y MiProximaExcepcion, que heredan de la clase Exception. El código Java comienza aquí… 1. /*Definicion de la clase MiBaseExcepcion comienza aqui*/ 2. class MiBaseExcepcion extends Exception{ 3. 4.

/* Constructor MiBaseExcepcion comienza aqui */ public MiBaseExcepcion() {

5. 6. 7.

super(); }/* Constructor MiBaseExcepcion termina aqui */

8. 9. 10.

/* Constructor MiBaseExcepcion comienza aqui */ public MiBaseExcepcion(String s) { super(s);

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 40

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

11. }/* Constructor MiBaseExcepcion termina aqui */ 12. }/* Definicion de la clase MiBaseExcepcion termina aqui */ 13. 14. /*Definicion de la clase MiSubExcepcion comienza aqui*/ 15. public class MiSubExcepcion extends MiBaseExcepcion{ 16. /* Constructor MiSubExcepcion comienza aqui */ 17. 18. 19.

public MiSubExcepcion() { super(); }/* Constructor MiSubExcepcion termina aqui */

20. 21.

/* Constructor MiSubExcepcion comienza aqui */

22. 23. 24.

public MiSubExcepcion(String s) { super(s); }/* Constructor MiSubExcepcion termina aqui */

25. }/* Definicion de la clase MiSubExcepcion termina aqui */ 26. 27. /*Definicion de la clase ProximaExcepcion comienza aqui*/ 28. class ProximaExcepcion extends Exception { 29. /* Constructor ProximaExcepcion comienza aqui */ 30. public ProximaExcepcion() { 31. 32. 33.

super(); }/* Constructor ProximaExcepcion termina aqui */

34. 35. 36.

/* Constructor ProximaExcepcion comienza aqui */ public ProximaExcepcion(String s) { super(s);

37. }/* Constructor ProximaExcepcion termina aqui */ 38. }/* Definicion de la clase ProximaExcepcion termina aqui */ El código Java termina aquí Aquí, se tiene tres excepciones creadas, MiSubExcepcion es subclase de MiBaseExcepcion, que a su vez es subclase de Exception. Por esto, MiSubExcepcion es indirectamente una subclase de la clase Exception. MProximaExcepcion es una subclase directa de la clase Exception. Fin del Ejemplo 2.5

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 41 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

7. Más de Excepciones Definidas por el Usuario A continuación se presentan otros ejemplos. Se usarán las clases InputStreamReader y BufferedReader en los ejemplos que siguen. Estas dos clases forman parte del paquete java.io y serán estudiadas en detalle en el Volumen 4, Unidad 1 – Archivos y Flujos. Seguidamente, se dará una breve explicación de estas clases ya que consisten en un método mejor para leer datos de consola que usar simplemente el método System.in.read(). La clase InputStreamReader lee bytes y los convierte en caracteres. Esta clase provee un puente entre flujos de bytes y caracteres. La clase BufferedReader almacena caracteres conforme los lee de un flujo de entrada de caracteres. Para crear un objeto InputStreamReader, se necesita un objeto InputStream como un argumento para el constructor de InputStreamReader. El InputStream que se puede pasar al constructor de InputStreamReader es System.in. Para crear un objeto de BufferedReader, se necesita un objeto de la clase Reader para el constructor de BufferedReader. Dado que InputStreamReader lee bytes, y los convierte en caracteres, se puede pasar un objeto de InputStreamReader como argumento al constructor de BufferedReader. Se presenta un extracto de código para entender bien este concepto: // Crear un objeto de InputStreamReader InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); Se pueden combinar las dos sentencias anteriores como sigue: BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); System.in se pasa como parámetro al constructor de InputStreamReader, que a su vez es el parámetro para el constructor de BufferedReader. Una vez creado un objeto BufferedReader, se pueden leer caracteres de consola usando el método readLine(), como sigue: br.readLine(); Esta instrucción retorna caracteres que pueden ser convertidos a un entero usando el método parseInt() de la clase Integer como sigue: total =Integer.parseInt(br.readLine()); // total es un int Usar BufferedReader para leer datos es una buena alternativa en vez de usar System.in.read(). Ejemplo 2.6

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 42

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Tómese el ejemplo de la clase Stack. Las principales operaciones que se hacen con una pila son push cuando se coloca un elemento en la pila y pop cuando se toma el elemento que está en el tope de la pila. Java provee excepciones estándar para indicar las excepciones que podrían ser lanzadas durante las operaciones de push y pop. Defínase un método llamado top, que se usa para obtener el elemento del tope de la pila sin removerlo de la pila. Se debe lanzar una excepción si se intenta obtener el elemento en el tope de una pila vacía. Se escribe una clase propia de excepción (PilaVaciaExcepcion), que será lanzada cuando se intenta obtener el elemento tope de una pila vacía. El siguiente programa ilustra esto: El código Java comienza aquí… 1. import java.io.BufferedReader; 2. import java.io.IOException; 3. import java.io.InputStreamReader; 4. import java.util.Stack; 5. 6. /*Definicion de la clase PilaVaciaExcepcion comienza aqui*/ 7. class PilaVaciaExcepcion extends Exception{ 8. /* Constructor PilaVaciaExcepcion comienza aqui */ 9. 10. 11.

public PilaVaciaExcepcion() { System.out.println("La pila esta vacia"); }/* Constructor PilaVaciaExcepcion termina aqui */

12. }/* Definicion de la clase PilaVaciaExcepcion termina aqui */ 13. 14. /*Definicion de la clase PilaEjemplo comienza aqui*/ 15. public class PilaEjemplo extends Stack { 16. /* Metodo top comienza aqui */ 17. public void top(PilaEjemplo pe) 18. 19. 20.

throws PilaVaciaExcepcion{

21. 22.

throw new PilaVaciaExcepcion(); }else{

23. 24. 25.

Integer a = (Integer) pe.pop(); System.out.println(a);

26. 27. 28.

if (pe.isEmpty()){

} }/* Metodo top termina aqui */ /* Metodo main comienza aqui */

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 43 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

29. 30. 31. 32. 33. 34.

Guía del Estudiante

public static void main(String[] args) { int total, numero; PilaEjemplo pila = new PilaEjemplo(); try { BufferedReader br = new BufferedReader(

35. 36. 37.

new InputStreamReader(System.in)); System.out.println( "Ingrese la cantidad de elementos de la pila");

38. 39.

total = Integer.parseInt(br.readLine());

40. 41. 42.

if (total != 0) { System.out.println("Ingrese los numeros");

43. 44. 45.

while (total > 0) { numero = Integer.parseInt(br.readLine()); pila.push(new Integer(numero));

46. 47. 48.

total--; }

49. 50. 51.

System.out.print( "El elemento que esta en el " + "tope de la pila es: ");

52. 53. 54.

/* Llamada a funcion para obtener un elemento del tope de la pila */

55. 56. 57.

} } catch (PilaVaciaExcepcion pv) {

58. 59. 60.

System.out.println(pv); } catch (IOException e) { e.printStackTrace();

61. 62.

} catch (NumberFormatException e) { System.out.println("Valor invalido");

63. 64. 65.

pila.top(pila);

System.exit(0); } }/* Metodo main termina aqui */

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 44

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

66. }/* Definicion de la clase PilaEjemplo termina aqui */ El código Java termina aquí El código es autoexplicativo. Ilustra el método para definir una excepción definida por el usuario. Esto se hace derivando de la clase predefinida Exception. Fin del Ejemplo 2.6 A continuación se explica el uso de la cláusula throws con excepciones definidas por el usuario.

8. La Cláusula throws Revisada Se requiere que un método Java especifique las excepciones que puede lanzar, que no son capturadas ni manejadas. Además de manejar excepciones estándar, la cláusula throws se usa también para manejar excepciones definidas por el usuario. Considere dos excepciones: ExcepcionA y ExcepcionB, en donde la ExcepcionA es la superclase de ExcepcionB. Considere un método prueba() en la clase SuperClaseDePrueba. SuperClaseDePrueba es la superclase de SubClaseDePrueba. El método prueba() declarado en SuperClaseDePrueba puede lanzar ExcepcionB, ExcepcionA o no lanzar ninguna excepción. Asuma que el método prueba() está sobrescrito en SubClaseDePrueba. Si el método prueba() declarado en SuperClaseDePrueba lanza la ExcepcionA: entonces el método sobrescrito en SubClaseDePrueba puede lanzar ExcepccionA, ExcepcionB o no lanzar ninguna excepción; esto se debe a que el método que sobrescribe sólo puede lanzar la excepción lanzada por el método en la superclase o una subclase de la excepción, o en última instancia, no lanzar ninguna excepción. Esto se muestra en la Figura 2.3.

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 45 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Figura 2.3: Herencia y la Cláusula throws

Un método puede capturar una excepción específica, manejarla y lanzar la misma excepción de nuevo desde el bloque catch. Aún en tal caso, se requiere que el método especifique la excepción usando la cláusula throws. La Figura 2.4 muestra un método algunMetodo() que captura AlgunaExcepcion usando un bloque catch, maneja la excepción y relanza AlgunaExcepcion desde el bloque catch. Aquí, algunMetodo() especifica AlgunaExcepcion en su declaración.

Figura 2.4: Especificando Excepciones que son Relanzadas

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 46

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

En la sección anterior se vio como la cláusula throws se puede usar para manejar excepciones definidas por el usuario. Antes de seguir examinando la definición de excepciones en clases definidas por el usuario, se presenta una breve discusión sobre usar clases excepción en Java con un ejemplo. Recuerde que todas las excepciones son subclases de la clase Throwable. Existen algunas cosas que se deben tener en cuenta cuando se usa la jerarquía de excepciones. Considere el Ejemplo 2.7. Ejemplo 2.7 Escriba un programa que usa la jerarquía de excepciones, para entender los aspectos involucrados en esto. El código Java comienza aquí… 1. /*Definicion de la clase MiBaseExcepcion comienza aqui*/ 2. class MiBaseExcepcion extends Exception{ 3. /* Constructor MiBaseExcepcion comienza aqui */ 4. public MiBaseExcepcion() { 5. 6. 7.

super(); }/* Constructor MiBaseExcepcion termina aqui */

8. 9.

/* Constructor MiBaseExcepcion comienza aqui */ public MiBaseExcepcion(String s) {

10. super(s); 11. }/* Constructor MiBaseExcepcion termina aqui */ 12. }/* Definicion de la clase MiBaseExcepcion termina aqui */ 13. 14. /*Definicion de la clase MiSubExcepcion comienza aqui*/ 15. class MiSubExcepcion extends MiBaseExcepcion{ 16. 17. 18.

/* Constructor MiSubExcepcion comienza aqui */ public MiSubExcepcion() { super();

19. 20. 21.

}/* Constructor MiSubExcepcion termina aqui */

22. 23. 24.

public MiSubExcepcion(String s) { super(s); }/* Constructor MiSubExcepcion termina aqui */

/* Constructor MiSubExcepcion comienza aqui */

25. }/* Definicion de la clase MiSubExcepcion termina aqui */ Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 47 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

26. 27. /*Definicion de la clase ExcepcionEjemplo comienza aqui*/ 28. public class ExcepcionEjemplo { 29. 30. 31. 32. 33. 34.

/* Metodo metodo1 comienza aqui */ public static void metodo1(int i) { try { metodo2(i); } catch (MiBaseExcepcion e) { System.out.print("MiBaseExcepcion: ");

35. 36.

System.out.println(e.getMessage()); System.out.println("Manejado en el metodo1");

37. 38. 39.

}/* Metodo metodo1 termina aqui */

40. 41. 42.

/* Metodo metodo2 comienza aqui */ public static void metodo2(int i) throws MiBaseExcepcion {

43. 44. 45.

}

int resultado; try {

46. 47. 48.

System.out.println("i = " + i); resultado = metodo3(i); System.out.print("metodo3(i) = " + resultado);

49. 50. 51.

} catch (MiSubExcepcion e) { System.out.print("MiSubExcepcion: "); System.out.println(e.getMessage());

52. 53. 54.

System.out.println("Manejado en el metodo2"); } finally { System.out.print("\n");

55. 56. 57.

} }/* Metodo metodo2 termina aqui */

58. 59.

/* Metodo metodo3 comienza aqui */ public static int metodo3(int i)

60. 61. 62.

throws MiBaseExcepcion, MiSubExcepcion { if (i < 0)

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 48

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

63. 64. 65.

Core Java

throw new MiBaseExcepcion("El valor es muy bajo"); else if (i > 99) throw new MiSubExcepcion("El valor es muy alto");

66. 67. 68.

else return i + i; }/* Metodo metodo3 termina aqui */

69. 70. 71.

/* Metodo main comienza aqui */ public static void main(String[] args) {

72. 73.

try { metodo1(99);

74. } catch (Exception e) {} 75. }/* Metodo main termina aqui */ 76. }/* Definicion de la clase ExcepcionEjemplo termina aqui */ El código Java termina aquí En el programa anterior, MiBaseExcepcion define dos constructores – una que no toma parámetros, y otro que toma un parámetro de tipo String. La excepción MiSubExcepcion que es subclase de MiBaseExcepcion sobrescribe los dos constructores de MiBaseExcepcion. La clase ExcepcionEjemplo define tres métodos: metodo1(), metodo2() y metodo3(). metodo1() invoca a metodo2() que a su vez invoca a metodo3(). metodo3() lanza dos excepciones, llamadas, MiBaseExcepcion y MiSubExcepcion. La excepción MiSubExcepcion, que es lanzada por metodo3(), es manejada por metodo2(). La excepción MiBaseExcepcion que es lanzada por metodo3() se pasa a metodo2(), que a su vez la pasa a metodo1(), que finalmente maneja la excepción. Si metodo2() manejara MiBaseExcepcion, entonces manejaría ambas MiBaseExcepcion y MiSubExcepcion cuando metodo3() lance estas excepciones. En este caso las excepciones no se pasarán a metodo1(). Fin del Ejemplo 2.7

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 49 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Resumen Ahora que ha completado esta unidad, usted será capaz de: •

Mencionar las excepciones estándar en Java.



Describir el uso de la jerarquía de excepciones.



Explicar como sobrescribir métodos que lanzan excepciones.



Crear excepciones definidas por el usuario.

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 50

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Unidad 2: Examen de Autoevaluación 1) ¿Cuál de las siguientes no son excepciones del tiempo de ejecución (runtime exceptions? a) Excepciones no verificadas. b) Excepciones definidas por el usuario. c) Excepciones verificadas. d) Ninguna de las anteriores. 2) La cláusula try/catch debe intentar ____________________. a) Capturar primero la excepción más genérica. b) Capturar primero la excepción menos genérica. c) Capturar las excepciones en cualquier orden, pero capturarlas todas. d) Ninguna de las anteriores. 3) Si hay un System.exit(0); dentro de un bloque try-catch entonces____________. a) Las sentencias dentro del finally todavía serán ejecutadas. b) El programador puede especificar si las sentencias en el finally deben ser ejecutadas. c) Es un error, dado que no se puede colocar esta sentencia allí. d) Las sentencias dentro del finally no serán ejecutadas. 4) Un método que sobrescribe en una subclase puede lanzar solo excepciones declaradas en su clase padre o hijas de las excepciones declaradas en su clase padre. ¿Cuándo es verdadero esto? a) Cuando existen métodos sobrescritos o métodos sobrecargados. b) Cuando sólo son métodos sobrescritos y no métodos sobrecargados. c) Cuando el programador establece explícitamente que el compilador ignore el error potencial. d) Ninguna de las anteriores. 5) ¿Cuál de las siguientes es una declaración correcta para una clase excepción definida por el usuario? a) class A extends B {…} b) class A extends B implements Exception {…} c) class A extends Exception {…} d) class A extends Exception implements B {…}

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 51 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

6) ¿Qué indica la cláusula throws de un método a los programadores cliente? a) Las excepciones que no han sido tomadas en cuenta. b) Las excepciones con las que deberá tratar cuando invoque al método. c) Las excepciones que puede ignorar cuando invoque al método. d) Ninguna de las anteriores. 7) Un método puede capturar una excepción específica, manejarla y lanzar la misma excepción de nuevo desde el bloque catch. a) Verdadero b) Falso 8) ¿Cuál es el primer paso para crear una excepción definida por el usuario? a) Declarar una clase, crear una subclase de esa clase, que implemente una clase Exception. b) Declarar una clase Exception. c) Declarar el constructor de la clase Exception. d) Declarar una clase que sea subclase de la clase Exception. 9) Un bloque try-catch debe siempre estar seguido por una cláusula finally. a) Verdadero b) Falso 10) La cláusula throws está disponible para indicar que un método puede actualmente lanzar una excepción. a) Verdadero b) Falso

Unidad 2: Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 52

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Respuestas a la Unidad 2: Examen de Autoevaluación 1) c 2) b 3) d 4) b 5) c y d 6) b 7) a 8) d 9) b 10) a

Libro 2: Core Java

Unidad 2: Lanzamiento y Manejo de Excepciones 53 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones Objetivos de Aprendizaje •

Manejar excepciones.



Usar las cláusulas throw y match.



Escribir excepciones definidas por el usuario.

Libro 2: Core Java

Volumen 3: Manejo de Excepciones 55 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Ejercicios de Laboratorio 1) Escriba un programa en Java que tenga una clase abstracta llamada Cuenta. Esta clase debe tener los siguientes miembros: private int id; private float saldo; abstract void depositar(float monto) throws MontoAnormalException; abstract void retirar(float monto) throws MontoInsuficienteException; El programa debe tener también dos clases concretas llamadas CuentaCorriente y CuentaAhorro que son subclases de la clase Cuenta. Los objetos de la clase CuentaCorriente pueden llegar a tener el saldo negativo luego de un retiro, al contrario de los objetos de la clase CuentaAhorro que no pueden llegar a tener saldo negativo. Las clases MontoAnormalException y MontoInsuficienteException son clases excepciones que deben ser manejadas en el programa. Debe escribir una clase Principal que permita crear instancias de CuentaCorriente y CuentaAhorro para verificar el manejo correcto de las excepciones. Recomendaciones Útiles: • • •

• • •

Escriba una clase llamada Cuenta que defina los miembros mencionados y métodos que permitan acceder a las variables private (geter y seter). El método depositar() acepta un dato float que representa el monto que se desea depositar en la cuenta. Este método lanza MontoAnormalException como advertencia cuando el monto a depositar excede los 10 millones de Bs. El método retirar() acepta una dato float que representa el monto que se desea retirar de la cuenta. Este método lanza MontoInsuficienteException cuando el monto a retirar es mayor al saldo disponible en la cuenta. Crear dos clases excepciones llamadas MontoInsuficienteException y MontoAnormalException que tengan mensajes acordes con el evento sucedido. Crear dos subclases de Cuenta llamadas CuentaCorriente y CuentaAhorro. Estas clases deben ser concretas, para esto deben implementar los métodos abstractos de su superclase. La clase CuentaCorriente debe permitir crear instancias de ella en donde sea posible tener saldos negativos sin lanzar ninguna excepción.

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 56

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

• •

Core Java

La clase CuentaAhorro debe permitir crear instancias de ella en donde no sea posible tener saldos negativos, cuando se intente retirar algún monto mayor al saldo disponible debe lanzar MontoInsuficienteException. Crear una clase llamada Principal que tenga el método main y en el cual se creen instancias de CuentaAhorro y CuentaCorriente para verificar el manejo correcto de las excepciones.

2) Escriba un programa en Java que tenga una clase llamada Autentica. Esta clase tiene los nombres de usuario y sus correspondientes palabras claves guardadas en arreglos String (declarados private). También tiene una variable boolean, accesoPermitido, cuyo valor por defecto es false. Existe un método llamado chequearClave() que verifica la palabra clave ingresada contra el nombre de usuario. Si la palabra clave ingresada es correcta, entonces imprime “Autenticación Verificada. Acceso al Usuario Permitido” en la salida estándar cambia el valor de accesoPermitido a true. Si la palabra clave ingresada es incorrecta entonces accesoPermitido se hace false y se lanza una excepción llamada PropiedadPrivadaExcepcion. PropiedadPrivadaExcepcion es una excepción definida por el usuario. La clase Usuario instancia la clase Autentica, e invoca al método chequearClave()para validar la palabra clave a fin de obtener acceso a DatoSecreto. Los datos en la clase DatoSecreto solo puede ser accedidos cuando accesoPermitido de Autentica es true, de otra forma se lanza una excepción AlertaDeIntrusoExcepcion, también definida por el usuario. Ambas excepciones PropiedadPrivadaExcepcion y AlertaDeIntrusoExcepcion tienen información que puede ser usada por Usuario cuando son capturadas. Recomendaciones Útiles: •

Escriba clases excepción llamadas PropiedadPrivadaExcepcion AlertaDeIntrusoExcepcion que extiendan de la clase Exception.



Escriba una clase llamada DatoSecreto que tenga una variable private y métodos para obtener y asignar valor a la variable private.



Escriba una clase Autentica y dentro de ella, declare dos arreglos de String que sean inicializadas con nombres de usuario y sus correspondientes palabras clave.



Declare una variable boolean, accesoPermitido inicializada en false.



Defina un método, chequearClave que revise si un nombre de usuario y palabra clave recibidos concuerdan con los del arreglo de String.



Escriba una clase, Usuario que acepte un nombre de usuario y una palabra clave y use el método chequearClave para autenticar al usuario.

Libro 2: Core Java

y

Volumen 3: Manejo de Excepciones 57 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante



Si el método chequearClave retorna true, entonces se imprime “Autenticación verificada. Acceso al Usuario Permitido” en la salida estándar y a la variable accesoPermitido se le asigna true.



Si el método chequearClave retorna PropiedadPrivadaExcepcion es lanzada.



Si la variable private en DatoSecreto se accesoPermitido es false, se lanza AlertaDeIntrusoExcepcion

3)

la

false,

excepción

accede cuando la excepción

Escriba un programa en Java que invierta una cadena dada. Si la cadena original y la cadena invertida son iguales, entonces lanza una excepción Palindrome, que es una excepción definida por el usuario.

Recomendaciones Útiles: •

Escriba una clase llamada PalindromeExcepcion que extiende de la clase Exception.



Escriba una clase CadenaInvertida que tenga una variable String inicializada con un valor string.



Forme un arreglo de caracteres de la variable String



Invierta el arreglo de caracteres y forme un String del arreglo invertido.



Compare la variable String inicial y la variable String obtenida de invertir el arreglo de caracteres usando el método equals().



Si el método equals() retorna true, imprimir “Es palíndrome” en la salida estándar, sino lanzar PalindromeExcepcion.

Unidad 3: Laboratorio de Lanzamiento y Manejo de Excepciones

Libro 2: Core Java 58

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Volumen 4: Facilidades de Entrada / Salida

Libro 2: Core Java

Volumen 4: Facilidades de Entrada / Salida 59 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Unidad 1: Archivos y Flujos Objetivos de Aprendizaje Al final de esta unidad, usted será capaz de: •

Entender la clase File.



Describir FileDescriptor.



Conocer acerca de los flujos.



Explicar los diferentes tipos de flujos de caracteres.



Explicar los diferentes tipos de flujos de bytes.



Mencionar la forma de trabajo con archivos de acceso aleatorio.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 61 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

1. Introducción Esta unidad se ocupa de la entrada y salida en Java. La mayoría de las aplicaciones requieren de datos que sean leídos de una fuente externa o datos que sean almacenados en una fuente externa. Los archivos se usan para almacenar, leer y escribir datos. Para hacer esto, primero se debe acceder a los archivos, la unidad trata con dos categorías de clases, que están relacionadas con archivos: •

Archivos.



Flujos.

Las clases relativas a los archivos trabajan con el sistema de archivos en la computadora. Los flujos, por otra parte, ayudan en funciones relativas a archivos como leer del archivo, escribir datos al archivo, leer y escribir datos sobre la red, etc. Imagine un flujo como un tubo donde es posible leer o escribir bytes y/o caracteres. No importa lo que pueda haber en el otro extremo del tubo: puede ser un teclado, un monitor, un archivo, un proceso, una conexión TCP/IP o un objeto Java. Todas las clases que manejan la entrada y salida de datos están disponibles en el paquete java.io. La Figura 1.1 da una visión general de algunas de las clases disponibles en el paquete java.io.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 62

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Figura 1.1: Clases para Entrada/Salida en el Paquete java.io

De la Figura 1.1, se puede notar lo siguiente: •

File, FileDescriptor, RandomAccessFile, ObjectStream, OutputStream, Reader y Writer derivan de la clase Object.

Libro 2: Core Java

InputStream,

Unidad 1: Archivos y Flujos 63 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java



Guía del Estudiante

Las clases InputStream, OutputStream, Reader y Writer tienen clases derivadas para realizar actividades específicas de entrada/salida.

Se estudiarán algunas de las clases de la figura en esta unidad, se comienza el tema con entrada/salida usando archivos.

2. Archivos Java provee soporte a archivos usando tres clases, llamadas, File, FileDescriptor y RandomAccessFile para usar el sistema de archivos en una computadora. A continuación se explicará primero la clase File.

2.1 La Clase File Los archivos son un mecanismo usado para almacenar información. Existen varias categorías de archivos, dependiendo del tipo de información que es almacenada y el sistema de archivos que se usa depende del sistema de operación usado en la computadora. Una categoría particular de archivos puede, típicamente, ser almacenada bajo un nombre de directorio. El nombre de directorio es un identificador que se usa para localizar una categoría en particular. Todos los archivos, por ejemplo, relacionados a un proyecto en particular pueden almacenarse bajo un directorio llamado proyecto. Se puede tener una jerarquía de directorios para almacenar varias categorías de archivos. Java permite acceder a los archivos almacenados en el sistema de archivos local usando la clase File, que es una representación abstracta de los archivos y directorios disponibles en el sistema de archivos local. Esta representación abstracta es independiente del sistema de operación o del hardware en el cual la JVM se está ejecutando. Los objetos de la clase File son inmutables, en otras palabras, una vez que se crea un objeto File para representar una ruta particular, no se puede modificar para apuntar a otra ruta, sólo es posible asignarle una instancia diferente de la clase File. La clase File extiende de la clase Object e implementa las siguientes interfaces: •

Serializable



Comparable

Como File implementa la interfaz Serializable, sus objetos pueden ser serializados y deserealizados. (Refiérase a la Unidad 3 – Serialización de Objetos de este volumen para información detallada acerca de la serialización/deserealización). File también implementa la interfaz Comparable y por esto se pueden comparar dos rutas de objetos File usando el método compareTo().

Unidad 1: Archivos y Flujos

Libro 2: Core Java 64

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

A continuación se escribe un programa simple en Java que ilustrará como crear un objeto de la clase File y mostrará algunos datos acerca del archivo abierto, usando la clase File. Ejemplo 1.1 El código Java comienza aquí... 1.

import java.io.File;

2. 3. /*Definicion de la clase DetalleArchivo comienza aqui*/ 4. public class DetalleArchivo { 5. /* Metodo main comienza aqui */ 6. public static void main(String[] args) { 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.

File a = new File("/home/student1/ejemplo.txt"); if (a.exists()) { System.out.println("* * * Datos del Archivo * * *"); System.out.println("Nombre: " + a.getName()); System.out.println("Ruta Completa: " + a.getPath()); System.out.println("Directorio Padre: " + a.getParent()); System.out.println("Tamano (en Bytes): " + a.length()); } else { System.out.println( "Archivo: " + a.getName() + " no existe");

19. } 20. }/* Metodo main termina aqui */ 21. }/* Definicion de la clase DetalleArchivo termina aqui */ El código Java termina aquí La salida del programa será la siguiente: * * * Datos del Archivo * * * Nombre: ejemplo.txt Ruta Completa: /home/student1/ejemplo.txt Directorio Padre: /home/student1 Tamano (en Bytes): 16 Nota: El objeto File es una abstracción de los archivos en el sistema. La creación de un objeto File no creará ningún archivo en el sistema de archivos.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 65 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

Fin del Ejemplo 1.1 A continuación se discuten los separadores de archivos en la ruta de archivos.

2.2 Separadores de Archivos Los separadores de archivos son aquellos que separan los subdirectorios en la ruta. Windows usa una barra invertida ‘\’ para separar los subdirectorios, en cambio UNIX usa una barra ‘/’ para separar los directorios. Como resultado, las rutas de archivos lucen diferentes en cada sistema de operación. Por ejemplo, en el Ejemplo 1.1, se usó la siguiente línea de código: File a = new File("/home/student1/ejemplo.txt"). Para evitar el problema de los separadores y el sistema operativo, se puede usar File.separator, que usa el separador por omisión del sistema de operación en el cual el programa se está ejecutando. El código anterior modificado con File.separator se da a continuación: File a = new File(File.separator+"home"+ File.separator+"student1"+ File.separator+"ejemplo.txt"); Este código puede ser usado en ambos Windows y UNIX. Ahora, se verán los descriptores de archivo.

2.3 La Clase FileDescriptor Esta clase se usa para manejar flujos de entrada, salida y error específicos para la máquina dentro de un programa Java. Esta clase tiene variables estáticas como manejadores para los siguientes tres flujos: •

FileDescriptor.in

- Maneja el flujo de entrada



FileDescriptor.out

- Maneja el flujo de salida



FileDescriptor.err

- Maneja el flujo de error

Típicamente, las aplicaciones no crean descriptores de archivo. FileDescriptor extiende de la clase Object. Los objetos FileInputStream, FileOutputStream, FileWriter y FileReader pueden ser creados usando el objeto FileDescriptor como argumento. El siguiente fragmento de código muestra como un objeto FileWriter se crea usando un objeto FileDescriptor. La clase FileWriter será discutida en una sección posterior. El código a continuación se usa simplemente para mostrar el uso de la clase FileDescriptor. Ejemplo 1.2 El código Java comienza aquí… 22. import java.io.FileDescriptor; Unidad 1: Archivos y Flujos

Libro 2: Core Java 66

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

23. import java.io.FileWriter; 24. 25. /*Definicion de la clase FileDescriptorEjemplo comienza aqui*/ 26. public class FileDescriptorEjemplo { 27. /* Metodo main comienza aqui */ 28. public static void main(String[] args) { 29. 30. 31. 32. 33. 34. 35. 36.

try { FileDescriptor fd = FileDescriptor.out; FileWriter fw = new FileWriter(fd); fw.write("Hola mundo!"); fw.close(); } catch (Exception e) { e.printStackTrace(); }

37. }/* Metodo main termina aqui */ 38. }/*Definicion de la clase FileDescriptorEjemplo termina aqui*/ El código Java termina aquí El objeto fd se crea usando el manejador para el flujo de salida FileDescriptor.out. fd y se le pasa entonces a FileWriter como argumento, durante su instanciación. Como resultado de compilar y ejecutar este programa se imprime en la consola de salida la frase Hola mundo! Fin del Ejemplo 1.2 En esta sección se aprendió acerca de la clase FileDescriptor, ahora se continuará con archivos que son accedidos de forma aleatoria.

2.4 Archivos de Acceso Aleatorio El paquete java.io tiene la clase RandomAccessFile. El acceso aleatorio a archivos se usa para leer y escribir datos en cualquier sitio en un archivo. El acceso secuencial a archivo requiere pasar por cada línea de datos en el archivo antes de encontrar la información requerida. Tómese un ejemplo para entender el acceso de datos aleatorio. Asuma que un archivo tiene las siguientes líneas de datos: Mike, 32, California Aaron, 31, New York Jane, 32, Ohio Richards, 29, Texas Libro 2: Core Java

Unidad 1: Archivos y Flujos 67 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

John, 31, Pennsylvania Para encontrar a Richards, que es el cuarto registro en la lista, el acceso secuencial requerirá pasar a través de los tres primeros registros. Pero usando la operación de seek en modo de acceso aleatorio, Richards puede ser encontrado sin pasar por los tres primeros registros. RandomAccessFile extiende de la clase Object e implementa las siguientes interfaces: •

DataOutput



DataInput

Los argumentos que se usan cuando se instancia una clase, ayudan a decidir si el objeto será usado para lectura o escritura. La siguiente línea de código crea un RandomAccessFile que se usa para leer del archivo entrada.txt. new RandomAccessFile("entrada.txt", "r"); La siguiente línea crea una clase RandomAccessFile que se usa para lectura y escritura en el archivo salida.txt: new RandomAccessFile("salida.txt", "rw"); El ”r” y ”rw” indican el modo de apertura del archivo de acceso aleatorio. Aquí ‘r’ denota sólo lectura, y ‘rw’ denota lectura-escritura. La clase RandomAccessFile provee soporte para el concepto de apuntador a archivo para indicar la ubicación actual en el archivo. En el momento de creación del archivo, el puntero de archivo se establece en 0, lo que indica el inicio del archivo. Luego el número de bytes que son leídos o escritos mueve el apuntador del archivo. Esta manipulación del apuntador a archivo se lleva a cabo en esta clase, usando los siguientes tres métodos: skipBytes(), seek() y getFilePointer(). El método skipBytes() mueve el apuntador de archivo hacia adelante el número de bytes especificado. El método seek() posiciona el apuntador de archivo exactamente antes del byte especificado. El método getFilePointer() permite obtener la ubicación actual del apuntador a archivo. En caso de que el fin de archivo se alcance antes de leer el número de bytes especificado, entonces se lanza una EOFException y en caso de no leer o escribir un byte, entonces se lanza una IOException. Una IOException puede ser lanzada también cuando un flujo está cerrado. Ejemplo 1.3 Este programa ilustra como leer y escribir datos a un archivo de acceso aleatorio.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 68

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

El código Java comienza aquí… 1. import java.io.File; 2. import java.io.FileNotFoundException; 3. import java.io.IOException; 4. import java.io.RandomAccessFile; 5. 6. /*Definicion de la clase comienza aqui*/ 7. public class RandomAccessFileEjemplo { 8. final static int POSICION_CARACTER = 2; 9. 10. 11.

static String nombreArchivo = "aleatorio.txt";

12. 13. 14.

public static void main(String args[]) { try { RandomAccessFileEjemplo aleatorio;

/* Metodo main comienza aqui */

15. 16. 17.

aleatorio = new RandomAccessFileEjemplo(); aleatorio.escribirAlfabeto(); aleatorio.leerAlfabeto();

18. 19. 20.

} catch (Exception e) { System.out.println(e); }

21. 22. 23.

}/* Metodo main termina aqui */

24. 25.

public void leerAlfabeto() throws IOException { try {

26. 27. 28.

File archivo = new File(nombreArchivo); RandomAccessFile raf; raf = new RandomAccessFile(archivo, "r");

29. 30. 31.

System.out.println( "\nAlfabeto desde el archivo " + nombreArchivo);

32. 33. 34.

long longitud = raf.length(); for (int i = POSICION_CARACTER; i < longitud;

/* Metodo leerAlfabeto comienza aqui */

35. 36. Libro 2: Core Java

i += 2 * POSICION_CARACTER) {

Unidad 1: Archivos y Flujos 69 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

37. 38. 39.

Guía del Estudiante

raf.seek(i); System.out.println(raf.readChar()); }// Fin del ciclo for

40. 41. 42.

raf.close(); } catch (FileNotFoundException e) { System.out.println("No se encuentra el archivo");

43. 44. 45.

System.exit(0); } catch (IOException e) { System.out.println(e);

46. 47.

} } /* Metodo leerAlfabeto termina aqui */

48. 49. 50.

/* Metodo escribirAlfabeto comienza aqui */ public void escribirAlfabeto() throws IOException {

51. 52. 53.

File archivo = new File(nombreArchivo); RandomAccessFile raf; raf = new RandomAccessFile(archivo, "rw");

54. 55. 56.

System.out.println( "Los datos a escribir en el archivo " + nombreArchivo + " son:");

57. 58. 59.

for (int i = 65; i < 91; i++) { raf.writeChar(i); System.out.print((char) i + " ");

60. 61. 62.

}// Fin del ciclo for System.out.println(); raf.close();

63. }/* Metodo escribirAlfabeto termina aqui */ 64. }/* Definicion de la clase termina aquí */ El código Java termina aquí La salida del programa anterior es como sigue: Los datos a escribir en el archivo aleatorio.txt son: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z Alfabeto desde el archivo aleatorio.txt B D

Unidad 1: Archivos y Flujos

Libro 2: Core Java 70

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

F H J L N P R T V X Z Fin del Ejemplo 1.3 En este programa, el archivo aleatorio.txt tiene las letras de la A a la Z. RandomAccessFile se usa para acceder en forma no secuencial cada segundo carácter almacenado en el archivo e imprimir en la salida estándar, sin pasar por cada carácter en forma secuencial. Ahora que se sabe como trabajar con archivos en Java, se explican los flujos y como se manejan en Java.

3. Flujos La entrada/salida en Java está basada en flujos. Java trata toda la información, independientemente de la fuente o el destino, como flujos. Los datos que son leídos y escritos en un programa Java son tratados como un flujo de datos, bytes continuos de datos que vienen y van. Estos bytes son leídos o escritos a archivos, conectores o conexiones en Internet. Los flujos son independientes del dispositivo. Un flujo en Java es cualquier ruta de información desde la fuente al destino. Los siguientes son algunos pares de fuentes y destinos: •

Un teclado (fuente) y un monitor (destino).



Una página de texto en un monitor (fuente) y un archivo en un disco duro (destino).



Un archivo en un disco duro (fuente) y un monitor (destino).



Un servidor web (fuente) y un navegador (destino).



Un teclado (fuente) y una cadena de caracteres (destino).



Un archivo de texto (fuente) y una impresora (destino).

Libro 2: Core Java

Unidad 1: Archivos y Flujos 71 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

El procesamiento de flujos en Java está bien abstraído e igualmente bien entendido. Esto hace a Java un lenguaje ideal para comunicaciones en red, porque incluye transferencias de datos desde la fuente hasta el destino. Considere la Figura 1.2, que ilustra el concepto de flujos en Java.

Figura 1.2: Flujos en Java

La lectura del o escritura al flujo en Java es igual a leer o escribir a un archivo en lenguajes como C o C++. Los pasos para realizar estas operaciones son los mismos que en C o C++. El algoritmo básico para leer usando un flujo se da a continuación: Paso 1: Abrir un flujo de la fuente de datos en el programa Java. Paso 2: Mientras haya datos disponibles en la fuente de datos, leerlos. Paso 3: Cerrar el flujo. El algoritmo básico para escribir usando un flujo se da a continuación: Paso 1: Abrir el flujo a destino de los datos en el programa Java.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 72

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Paso 2: Mientras haya datos disponibles en el programa Java, escribirlos. Paso 3: Cerrar el flujo. Ambos algoritmos dan los tres pasos básicos requeridos para lectura y escritura usando flujos. Así, cualquiera sea los tipos de datos leídos o escritos, será fácil para los programadores usar clases de entrada/salida de Java. Los flujos en Java están bien organizados y se clasifican en los siguientes dos grupos: •

Flujos de Byte.



Flujos de Carácter.

Estos dos tipos de flujos permiten acceder datos de una manera secuencial. Los flujos de byte se usan para transferir 8-bits de datos, mientras que los flujos de caracteres trabajan con caracteres de 16-bit Unicode. Los flujos de byte son representados en Java con las clases: •

InputStream.



OutputStream.

Los flujos de caracteres son representados con las clases: •

Reader.



Writer.

Java considera un enfoque internacional para los caracteres; se usan dos bytes para representar un carácter. Las clases InputStream y OutputStream no pueden procesar caracteres Unicode de una forma eficiente, para esto fueron creadas las clases Reader y Writer en Java. La Figura 1.3 muestra los flujos de byte y de carácter en Java.

Figura 1.3: Flujos de Byte y Flujos de Carácter

Libro 2: Core Java

Unidad 1: Archivos y Flujos 73 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

A continuación se estudian cada una de estas cuatro clases, llamadas, InputStream, OutputStream, Reader y Writer, en detalle.

4. La Clase InputStream La clase InputStream es una clase abstracta que permite leer bytes (8-bit) de datos. Esta clase extiende de la clase Object. Las clases que heredan de InputStream deben implementar un método que retorne el próximo byte de datos del flujo que se está leyendo. Las subclases de la clase InputStream se muestran en la Figura 1.4.

Figura 1.4: La Clase InputStream y sus Subclases

Se discutirá acerca de ObjectInputStream en la Unidad 3 – Serialización de Objetos, la cual se usa para de-serializar objetos durante la serialización de objetos. Todas las otras clases serán discutidas en esta unidad. Se comenzará con ByteArrayInputStream.

4.1 La Clase ByteArrayInputStream La clase ByteArrayInputStream es una de las subclases de InputStream. Se ha mencionado que si una clase es subclase de la clase InputStream, tiene que implementar un método para devolver el próximo byte de la entrada del flujo que se está leyendo. La clase ByteArrayInputStream provee este método al tener un buffer interno de datos y un contador que representa el próximo byte en el buffer. El ejemplo a continuación muestra la clase ByteArrayInputStream. Unidad 1: Archivos y Flujos

Libro 2: Core Java 74

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Ejemplo 1.4 El ejemplo ilustra la lectura en un string que el usuario introduce y se muestra el string usando un objeto ByteArrayInputStream. El código Java comienza aquí… 1.

import java.io.ByteArrayInputStream;

2. 3. /*Definicion de la clase comienza aqui*/ 4. public class ByteArrayInputStreamEjemplo { 5. /* Metodo main comienza aqui */ 6. public static void main(String[] args) { 7. 8. 9.

String frase = "Hola mundo!";

10. 11. 12.

byte arregloBytes[] = frase.getBytes();

13. 14. 15.

ByteArrayInputStream bais; bais = new ByteArrayInputStream(arregloBytes);

16. 17. 18.

System.out.println("ByteArrayInputStream obtuvo: "); int caracterLeido; Character caracter = null;

19. 20. 21.

/* Leer de ByteArrayInputStream y mostrar en mayuscula */

22. 23. 24.

while ((caracterLeido = bais.read()) != -1){ caracter = Character.toUpperCase((char) caracterLeido); System.out.print(caracter);

25. 26.

} bais.reset();

/* Declaracion arreglo de byte */

/* Crear una instancia de ByteArrayInputStream */

27. }/* Metodo main termina aqui */ 28. }/* Definicion de la clase termina aqui */ El código Java termina aquí La salida del programa anterior es como sigue: ByteArrayInputStream obtuvo: Libro 2: Core Java

Unidad 1: Archivos y Flujos 75 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

HOLA MUNDO! Fin del Ejemplo 1.4 El programa del Ejemplo 1.4 toma el string hola mundo! como entrada, y lo lee usando el ByteArrayInputStream y se imprime en la salida estándar usando letras mayúsculas. La próxima clase que se estudia es la FileInputStream.

4.2 La Clase FileInputStream La clase FileInputStream se usa para leer el contenido de un archivo en forma de bytes. Los tipos de archivos que están disponibles dependen del sistema de archivos usado por el sistema de operación subyacente. La clase FileInputStream extiende de InputStream. Considere el ejemplo 1.5, que muestra el uso de la clase FileInputStream. Ejemplo 1.5 El código Java comienza aquí... 1.

import java.io.FileInputStream;

2. import java.io.FileNotFoundException; 3. import java.io.InputStream; 4. 5. /*Definicion de la clase comienza aqui*/ 6. public class FileInputStreamEjemplo { 7. 8. 9.

/* Metodo main comienza aqui */ public static void main(String[] args) { try {

10. 11. 12.

int cantidad; String nombreArchivo = "miArchivo.txt"; InputStream ie;

13. 14. 15.

ie = new FileInputStream(nombreArchivo); cantidad = ie.available(); System.out.println(

16. 17. 18.

"Leyendo desde el archivo: " + nombreArchivo); System.out.println(

19.

"Total bytes disponibles: " +

Unidad 1: Archivos y Flujos

Libro 2: Core Java 76

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

20. 21. 22.

cantidad + "\n"); /* Mostrar los datos de byte

23. 24. 25.

disponible a la salida estandar */ for (int i = 0; i < cantidad; i++) { System.out.print((char) ie.read());

26. 27. 28.

} /* Cerrar el InputStream */

29. 30.

ie.close(); } catch (FileNotFoundException e) {

31. 32. 33.

System.out.println("Archivo no encontrado"); System.exit(0); } catch (Exception e) {

34. 35. 36.

System.out.println(e); } // Fin del bloque Exception }/* Metodo main termina aqui */

37. }/* Definicion de la clase termina aqui */ El código Java termina aquí El contenido de miArchivo.txt es el siguiente: El BufferedReader es un tipo de Reader(lector). Se utiliza para leer los caracteres o Strings desde el flujo de entrada La salida del programa anterior es la siguiente: Leyendo desde el archivo: miArchivo.txt Total bytes disponibles: 121 El BufferedReader es un tipo de Reader(lector). Se utiliza para leer los caracteres o Strings desde el flujo de entrada Fin del Ejemplo 1.5 En el programa anterior, se leen bytes de datos del archivo miArchivo.txt, usando FileInputStream y se imprimen en la salida estándar.

Libro 2: Core Java

Unidad 1: Archivos y Flujos 77 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

4.3 La Clase FilterInputStream FilterInputStream, como el nombre sugiere, se usa para trabajar en el flujo de

entrada, manipulando los datos de entrada basado en ciertos filtros (condiciones) definidas por el usuario. La clase FilterInputStream extiende de InputStream. La condición del filtro puede estar basada en varias condiciones, como leer sólo caracteres ASCII o leer los caracteres de un rango específico, etc. FilterInputStream se ilustra en el Ejemplo 1.5. Ejemplo 1.6 El ejemplo muestra la creación de un objeto FilterInputStream y su uso. El código Java comienza aquí… 1. import java.io.FileInputStream; 2. import java.io.FilterInputStream; 3. import java.io.IOException; 4. import java.io.InputStream; 5. 6. /*Definicion de la clase comienza aqui*/ 7. public class FilterInputStreamEjemplo 8. extends FilterInputStream { 9. 10. 11.

/* Constructor FilterInputStreamEjemplo comienza aqui */ protected FilterInputStreamEjemplo(InputStream in) {

12. 13. 14.

super(in); }/* Constructor FilterInputStreamEjemplo termina aqui */

15. 16. 17.

/* Metodo read comienza aqui */ public int read() throws IOException { int valor = in.read();

18. 19. 20. 21. 22. 23. 24. 25.

/* Imprimir Alfabeto */ if ((valor >= 'A' && valor = 'a' && valor 126) datos[i] = (byte) '?'; }

55. 56. 57.

return resultado; } /* Metodo read sobrecargado termina aqui */

58. 59.

/* Metodo main comienza aqui */

60. 61. 62.

public static void main(String[] args) throws IOException{

Libro 2: Core Java

Unidad 1: Archivos y Flujos 79 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

63. 64. 65.

for (int i = 0; i < args.length; i++) { FilterInputStreamEjemplo fise;

66. 67. 68.

fise = new FilterInputStreamEjemplo( new FileInputStream(args[i]) );

69. 70. 71.

while (true) { int c = fise.read();

72. 73.

if (c == -1) break;

74. 75. 76.

System.out.print((char) c); } }

77. }/* Metodo main termina aqui */ 78. }/* Definicion de la clase termina aqui */ El código Java termina aquí Este programa filtra el flujo de entrada para permitir solo letras. El archivo palabras.txt que se pasa como argumento por la línea de comandos tiene el siguiente contenido: Bienvenido a IBM, este programa ilustra el uso de FileInputStream Al introducir el siguiente comando: java FilterInputStreamEjemplo palabras.txt La salida del programa será la siguiente: Bienvenido?a?IBM??este?programa?ilustra?el?uso?de?FileInpu tStream Fin del Ejemplo 1.6 El programa del Ejemplo 1.6 lee el contenido del archivo palabras.txt carácter por carácter y los imprime en la salida estándar únicamente si son letras del alfabeto. Si FilterInputStream lee un carácter no imprimible, el carácter es filtrado y se imprime un signo de interrogación (?) en la salida estándar. A continuación se explican las cuatro subclases de la clase FilterInputStream.

Unidad 1: Archivos y Flujos

Libro 2: Core Java 80

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

4.4 La Clase BufferedInputStream La clase BufferedInputStream permite que los flujos de entrada almacenen en un buffer los bytes de datos que son leídos. Los datos leídos de los flujos usualmente no son almacenados en un buffer. Sólo cuando los datos son leídos del flujo, los próximos datos llegan al flujo. BufferedInputStream también es subclase de FilterInputStream. BufferedInputStream mantiene un arreglo que representa el buffer interno. Cuando se leen bytes del flujo, el flujo de entrada rellena el buffer interno con un número de bytes, a la vez. Esto permite lecturas más rápidas de datos, porque estos están pre-almacenados. Ejemplo 1.7 Este programa muestra el uso de BufferedInputStream para leer datos de un archivo y cuenta la cantidad de líneas que tiene el archivo. El código Java comienza aquí… 1.

import java.io.BufferedInputStream;

2. import java.io.FileInputStream; 3. import java.io.IOException; 4. 5. /*Definicion de la clase comienza aqui*/ 6. public class BufferedInputStreamEjemplo { 7. /* Metodo main comienza aqui */ 8. 9. 10.

public static void main(String[] args) { if (args.length != 1) { System.err.println(

11. 12. 13.

"uso: BufferedInputStreamEjemplo nombreArchivo"); System.exit(1); }

14. 15. 16.

try { BufferedInputStream bis;

17. 18.

bis = new BufferedInputStream( new FileInputStream(args[0])

19. 20. 21.

); int contador = 1; int b;

22. 23.

while ((b = bis.read()) != -1) {

Libro 2: Core Java

Unidad 1: Archivos y Flujos 81 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

24. 25. 26.

if (b == '\n') contador++; }

27. 28. 29.

bis.close(); System.out.println(

30. 31. 32.

"El archivo contiene " + contador + " lineas");

33. 34.

} catch (IOException e) { System.err.println(e);

35. } 36. }/* Metodo main termina aqui */ 37. }/* Definicion de la clase termina aqui */ El código Java termina aquí Suponiendo que el archivo palabras.txt tenga lo siguiente: Bienvenido a IBM La salida del programa anterior será la siguiente: El archivo contiene 2 lineas Fin del Ejemplo 1.7 El programa anterior acepta un nombre de archivo de la línea de comandos. Abre el archivo especificado usando BufferedInputStream, lee el contenido del archivo, byte a byte. Cuando se encuentra el carácter ‘\n’, el valor del contador de líneas es incrementado. Finalmente, muestra el total de líneas en la salida estándar.

4.5 La Clase DataInputStream Los tipos de datos primitivos usualmente tienen una representación dependiente de la máquina subyacente. La clase DataInputStream permite que una aplicación lea los tipos de datos primitivos en una forma que es independiente de la máquina. La clase DataInputStream extiende a FilterInputStream. Representa cadenas Unicode en un formato que es una modificación menor del formato UTF-8. Los detalles exactos de la representación interna de los tipos de datos primitivos en esta clase están más allá del alcance de esta discusión.

Ejemplo 1.8 Unidad 1: Archivos y Flujos

Libro 2: Core Java 82

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

El código Java comienza aquí… 1. import java.io.BufferedInputStream; 2. import java.io.DataInputStream; 3. import java.io.FileInputStream; 4. import java.io.FileNotFoundException; 5. import java.io.IOException; 6. 7. /*Definicion de la clase comienza aqui*/ 8. public class DataInputStreamEjemplo { 9. 10. 11.

/* Metodo main comienza aqui */ public static void main(String[] args) { try {

12. 13. 14.

String nombreArchivo = "miArchivo.txt"; DataInputStream in;

15. 16. 17.

in = new DataInputStream( new BufferedInputStream( new FileInputStream(nombreArchivo)

18. 19. 20.

) );

21. 22. 23.

System.out.println( "Leyendo el archivo: " + nombreArchivo +

24. 25.

". Su contenido es: "

26. 27. 28.

+ "\n");

/* Mientras no sea el fin del archivo */ while (in.available() != 0) System.out.print((char) in.readByte());

29. 30. 31.

} catch (FileNotFoundException e) { System.out.println("Archivo no encontrado"); System.exit(0);

32. 33. 34.

} catch (IOException e) { System.err.println("IOException"); }

35. }/* Metodo main termina aqui */ 36. }/* Definicion de la clase termina aqui */ Libro 2: Core Java

Unidad 1: Archivos y Flujos 83 © Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Core Java

Guía del Estudiante

El código Java termina aquí El contenido de miArchivo.txt es el siguiente: El BufferedReader es un tipo de Reader(lector). Se utiliza para leer los caracteres o Strings desde el flujo de entrada La salida del programa es la siguiente: Leyendo el archivo: miArchivo.txt. Su contenido es: El BufferedReader es un tipo de Reader(lector). Se utiliza para leer los caracteres o Strings desde el flujo de entrada Fin del Ejemplo 1.8 En el programa anterior, un DataInputStream lee el contenido de miArchivo.txt byte por byte e imprime el byte leído en la salida estándar.

4.6 La Clase LineNumberInputStream Esta clase es ahora obsoleta (deprecated). La clase LineNumberInputStream puede ser usada si se necesita el número de la línea actual de los datos leídos. El número de la línea actual es incrementado cuando el flujo tiene el carácter de fin de línea (retorno de carro '\r', nueva línea '\n', o retorno de carro y nueva línea ‘\r’ y ‘\n’). LineNumberInputStream extiende de FilterInputStream.

4.7 La Clase PushbackInputStream En los flujos vistos hasta ahora, una vez leídos los datos, son removidos del flujo. Con la clase PushbackInputStream, es posible que un dato que es leído del flujo sea colocado de nuevo en el flujo. Es útil cuando se leen bytes de datos que están delimitados por un byte específico, que el último byte leído pueda ser “des-leído”, de forma que la próxima operación pueda leerlo de nuevo. La clase PushbackInputStream extiende a la clase FilterInputStream.

Ejemplo 1.9

Unidad 1: Archivos y Flujos

Libro 2: Core Java 84

© Copyright IBM Corp. 2007 Los materiales del curso no pueden ser reproducidos total o parcialmente sin el previo permiso escrito de IBM.

Guía del Estudiante

Core Java

Este programa ilustra el uso de la clase PushbackInputStream, usada con caracteres que son leídos byte por byte de un string. El código Java comienza aquí… 1. import java.io.ByteArrayInputStream; 2. import java.io.IOException; 3. import java.io.PushbackInputStream; 4. 5. /*Definicion de la clase comienza aqui*/ 6. public class PushbackInputStreamEjemplo { 7. 8. 9.

/* Metodo main comienza aqui */ public static void main(String[] args) { try {

10. 11. 12.

String texto = "if (marca==75)\n" + "resultado=distincion;\n"; byte arregloBytes[] = texto.getBytes();

13. 14.

/* Crear una instancia de ByteArrayInputStream */

15. 16. 17.

ByteArrayInputStream bais; bais = new ByteArrayInputStream(arregloBytes);

18. 19. 20.

/* Crear una instancia de PushbackInputStream */ PushbackInputStream pis; pis = new PushbackInputStream(bais);

21. 22. 23.

int caracter; while ((caracter = pis.read()) != -1) {

24. 25. 26.

if (caracter == '=') { if ((caracter = pis.read()) == '=') System.out.print(".eq.");

27. 28. 29.

else { System.out.print("