Programacion Orientada a Objetos (Java)

292
SSD3: Programación y Diseño Orientado a Objetos Unidad 1. Diseño de Clases Unidad 2. Implementación de Clases Unidad 3. Implementación Avanzada de Clases

description

Breve libro que ayudara a entender como funciona la Programación Orienta a Objetos en Java.

Transcript of Programacion Orientada a Objetos (Java)

  • SSD3: Programacin y Diseo Orientado a Objetos Unidad 1. Diseo de Clases Unidad 2. Implementacin de Clases Unidad 3. Implementacin Avanzada de Clases

  • Introduccin

    Este curso introduce a los alumnos a la solucin de problemas por medio del diseo y la programacin orientada a objetos. El nfasis est en el anlisis del problema y el diseo de la solucin, la documentacin y la implementacin. Los alumnos utilizan bibliotecas comerciales de software, y crean proyectos de software. Los ejercicios de programacin se llevan a cabo en Java.

    Libro

    Barker, Jacquie. Beginning Java Objects: From Concepts to Code. Primera Edicin, Apress, 2000.

    o

    Barker, Jacquie. Beginning Java Objects: From Concepts to Code. Segunda Edicin, Apress, 2005.

    Las tareas de lectura se indican dentro del contenido del curso. Adems, una lista completa se encuentra en Apndice D. Lecturas.

    Requerimientos de Software

    Java 2 Platform Standard Edition 5.0 Eclipse 3.1.x con el plug-in EclipseUML , u otro ambiente de programacin de Java

    con depurador y editor de UML.

    El propsito de SSD3 es que los alumnos

    1. Aprendan a programar utilizando tcnicas orientadas a objetos. 2. Aprender a disead clases extensibles y robustas. 3. Aprender a expresar diseos utilizando UML. 4. Aprender a escribir programas escribiendo clases e interfaces cooperativas.

    Los alumnos que terminen exitosamente SSD3 sern capaces de

    I. Producir 1. Programas de java que exhiban elementos de programacin orientada a

    objetos, incluyendo herencia, polimorfismo, clases abstractas e interfaces 2. Clases de Java robustas utilizando excepciones y modificadores de acceso 3. Diseos orientado a objetos utilizando UML 4. Implementaciones de Java a partir de una especificacin 5. Extensiones a programas de Java existentes para mejorar el desempeo o

    aadir funcionalidad 6. Cdigo con calidad profesional aplicando convenciones de cdigo utilizados

    en la industria

  • II. Utilizar 1. Herramientas profesionales comnmente utilizadas tales como depuradores

    (debuggers), ambientes de desarrollo (IDE), y editores de UML 2. Clases y paquetes utilitarios que involucran E/S (I/O), y tokenizacin 3. Clases de Java Swing para implementar Interfaces Grficas de Usuarios

    (GUI) 4. Recursos en lnea para mantenerse al corriente de los desarrollos de Java 5. Patrones de Diseo 6. Casos de prueba para la prueba de unidades (unit testing) 7. Colecciones e iteradores

    III. Discutir de Manera Informada sobre 1. Conceptos avanzados de orientacin a objetos

    IV. Posicionarse como Programador de Java

    Al completar exitosamente este curso, el estudiante ser capaz de (a) llevar a cabo tareas de programacin tales como extender la funcionalidad de programas existentes y mejorar el desempeo de mdulos de programas existentes, (b) implementar Interfaces Grficas de Usuario (GUI) en Java, (c) implementar programas que exhiban un comportamiento especificado, y (d) depurar y corregir programas que no se comportan de acuerdo a una especificacin.

  • Unidad 1. Diseo de Clases 1.1 Aplicaciones de Java 1.2 Diseando Clases

  • 1.1 Aplicaciones de Java 1.1.1 Aplicaciones en Java 1.1.2 Usando Eclipse 1.1.3 Comenzando con el API de Java 1.1.4 Consola E/S (I/O) 1.1.5 Objetos Excepcin 1.1.6 Convenciones de Cdigo 1.1.7 Javadoc 1.1.8 Depurando 1.1.9 Depurando con Eclipse

  • 1.1.1 Aplicaciones en Java Applets en Java Aplicaciones en Java

    Lecturas:

    Requeridas: o Barker, primera edicin, captulo 1 (pginas 137). o Barker, segunda edicin, captulo 2 (pginas 1532).

    Secuencia: Leer el libro de texto antes de leer esta pgina.

    Applets en Java

    Los programas de Java se presentan en muchas variantes: applets, servlets y aplicaciones. Los applets son referenciados desde las pginas Web e interpretadas por navegadores Web. Cada applet contiene una clase pblica que extiende la clase Applet.

    El siguiente es un applet que genera un mensaje como salida:

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10:

    import java.applet.*; import java.awt.*; public class MyApplet extends Applet { public void paint(Graphics g) { g.drawString("This is an applet!\n", 10, 10); } }

    Listado 1 MyApplet.java

    Aplicaciones en Java

    Las aplicaciones de Java son programas "autnomos", interpretados por un intrprete de Java (no por un navegador Web) sobre un sistema anfitrin. Para ejecutar una aplicacin de Java, el usuario escribe un comando que invoca el intrprete de Java en la aplicacin especificada.

  • Figura 1 Comando para ejecutar MyApplication

    En este ejemplo, el comando java llama al intrprete de Java y MyApplication es el nombre de la clase que ser ejecutada. El sistema operativo comienza la ejecucin llamando al mtodo main de la clase MyApplication. Las aplicaciones pueden consistir de una o muchas clases; una de estas clases debe tener un mtodo main. El mtodo main tiene la siguiente firma.

    public static void main(String[] args)

    El mtodo main tiene un parmetro de entrada, un arreglo String que contiene argumentos de lnea de comando que el usuario puede haber especificado al teclear el comando java. Los argumentos de lnea de comando permiten al usuario pasar informacin a la aplicacin. No utilizaremos argumentos de lnea de comando en este curso.

    La siguiente es una aplicacin simple que despliega las palabras en la pantalla: "This is my first application!" ("sta es mi primera aplicacin!").

    1: 2: 3: 4: 5: 6: 7:

    public class MyApplication { public static void main(String[] args) { System.out.println("This is my first application!"); } }

    Listado 2 MyApplication.java

    La clase que contiene el mtodo main debe ser public. La declaracin de clase puede o no tener una clusula extends; en este aspecto, las aplicaciones difieren de los applets. Los nombres de clases deben tener la primera letra de cada palabra en maysculas y no deben contener ningn guin bajo ( _ ). Por ejemplo, el nombre WordCount cumple con la convencin, mientras que wordCount, wordcount y word_count no lo hacen. El archivo que contiene el cdigo fuente debe tener el mismo nombre que la clase que contiene y usar la extensin .java. Por ejemplo, el archivo que contiene la clase WordCount debe ser nombrado WordCount.java.

    La siguiente figura muestra la salida de la clase MyApplication.

  • Figura 2 Ejecucin de MyApplication

  • 1.1.2 Usando Eclipse Introduccin Crear el Proyecto Crear la Clase Compilar la Clase Ejecutar la Aplicacin

    Introduccin

    Un Ambiente Integrado de Desarrollo (Integrated Development Environment o IDE por sus siglas en ingls) es una herramienta utilizada por los desarrolladores de sistemas para ayudarlos durante las diferentes fases del desarrollo de sistemas. Eclipse es un IDE de cdigo abierto (open source) que soporta muchos lenguajes de programacin. Eclipse viene con un Ambiente de Desarrollo de Java (Java Development Environment o JDE) que incluye un editor de resalte de sintaxis, un compilador, un depurador, un navegador de clases y un administrador de archivo/proyecto. La funcionalidad de Eclipse puede ser extendido con plug-ins tales como plug-ins de UML para modelacin Orientada a Objetos.

    En esta pgina, te mostraremos cmo crear y ejecutar la aplicacin MyApplication.

    Crear el Proyecto

    El primer paso es crear un proyecto de Java:

    1. En el men File (archivo), apunta a New (nuevo) y despus haz un clic en Project (proyecto).

    2. En el asistente de New Project (nuevo proyecto), presiona Java en el panel izquierdo, selecciona Java Project (proyecto de java) en el panel derecho y despus da un clic en Next (siguiente).

  • Figura 1 Asistente de Proyecto Nuevo (New Project)

    3. En el cuadro Project name (nombre de proyecto), escribe MyApplication. Selecciona el cuadro Use default (utilizar predeterminado) y da un clic en Finish (terminar).

  • Figura 2 Cuadro de Dilogo de Nuevo Proyecto de Java (New Java Project)

    4. Eclipse crear un nuevo proyecto de Java y desplegar la perspectiva de Java, una de las interfases de Eclipse para trabajar en un proyecto de Java. La perspectiva de Java ofrece varias herramientas incluyendo un editor de cdigo, un navegador de archivos y un navegador de clases.

  • Figura 3 Perspectiva de Java

    5. Puedes cambiar la perspectiva del proyecto. En el men Window (ventana), selecciona Open Perspective (abrir perspectiva) y elige la perspectiva deseada. Tambin puedes dar un clic en el icono de la perspectiva deseada en la barra de acceso directo en el extremo izquierdo de la ventana.

    Figura 4 Barra de acceso directo de Perspectivas

    Crear la Clase

    1. En el men File (archivo), apunta a New (nuevo) y da un clic en Class (clase). 2. En el asistente de Nueva Clase de Java o New Java Class, escribe MyApplication en

    el cuadro Name (nombre) y despus selecciona Finish (terminar).

  • Figura 5 Asistente New Class (Nueva Clase)

    3. Eclipse desplegar una plantilla para una nueva clase llamada MyApplication.

  • Figura 6 Plantilla para una nueva clase

    4. En el men Window (ventana), apunta a Open Perspective (abrir perspectiva) y presiona en Java Browsing (navegacin en Java). Esta perspectiva contiene un editor de Java y varias vistas del proyecto. Si el usuario presiona algn elemento en las vistas Types (tipos) o Members (miembros), el editor desplegar el cdigo para dicho elemento.

    o La vista Projects (proyectos) muestra proyectos de Java, carpetas fuente, libreras externas e internas.

    o La vista Packages (paquetes) lista los paquetes de clases en el proyecto seleccionado.

    o La vista Types (tipos) lista las clases del paquete seleccionado. o La vista Members (miembros) muestra las variables y los mtodos de la

    clase seleccionada. 5. Introduce el cdigo de MyApplication. Ver el listado 2

  • Figura 7 Cdigo de MyApplication.java

    Compilar la Clase

    Eclipse incluye un compilador de Java incremental. Cuando introduces una lnea de cdigo que contiene un error, el editor desplegar, en la derecha, una marca roja junto a dicha lnea de cdigo.

    1. Introduce un error de sintaxis borrando el punto y coma ( ; ) al final de la lnea que contiene System.out.println. El editor desplegar una marca roja.

    2. Apunta sobre la marca roja para desplegar el mensaje de error.

  • Figura 8 Mensaje de error de sintaxis

    3. Corrige el error aadiendo el punto y coma ( ; ). La marca roja desaparecer.

    Ejecutar la Aplicacin

    1. Comienza por crear una configuracin inicial para el proyecto MyApplication. Da un clic en MyApplication en la vista Projects (proyectos), presiona la flecha a la derecha del botn Run (ejecutar) en la barra de herramientas y despus presiona Run....

    Figura 9 Ejecuta la aplicacin de Java

    2. En el cuadro de dilogo de Run (ejecutar), escribe MyApplication en el cuadro Main class (clase principal) y despus presiona Run (ejecutar).

  • Figura 10 Creando la configuracin

    3. Una vez que se ha establecido la configuracin inicial, el usuario puede ejecutar la aplicacin dando un clic en la flecha que se encuentra a la derecha del botn Run en la barra de herramientas, apuntando a Run As (ejecutar como) y despus haciendo clic en Java Application (aplicacin de Java).

    Figura 11 Ejecutando la aplicacin

    4. Si la clase de Java no ha sido guardada, Eclipse desplegar un cuadro de dilogo para guardar los archivos del proyecto de Java. Presiona OK.

  • Figura 12 Guarda el proyecto de Java

    5. Eclipse desplegar el mensaje en la vista Console (consola) que aparece en la parte inferior de la ventana.

    Figura 13 Salida de la Consola

    6. La vista Console (consola) despliega la salida de la aplicacin. Si una aplicacin utiliza avisos para solicitar la entrada del usuario, dichos indicadores son desplegados en la vista Console. El usuario responde a un indicador escribiendo en la vista Console. El color de la vista Console codifica la salida estndar, error estndar y entrada estndar. Para una discusin del paquete java.io, ver la pgina Consola E/S (I/O). Los colores predeterminados son:

    o Azul para salida estndar o Rojo para error estndar (mensajes de error e indicadores) o Verde para entrada estndar

  • 1.1.3 Comenzando con el API de Java Introduccin Paquetes y el Estatuto import La Clase java.lang.String La Clase java.util.StringTokenizer Las Clases de Envoltura (Wrapper Classes)

    Introduccin

    El API (Interfaz de Programacin de Aplicaciones o Application Programming Interface) de Java representa una librera de Java extensiva. Estas libreras son escritas cuidadosamente, son robustas y estn probadas exitosamente.

    La documentacin del API de Java es generada por la herramienta Javadoc. Javadoc produce un conjunto de pginas HTML a partir de los comentarios Javadoc de un archivo fuente de Java. Los comentarios Javadoc documentan las clases, variables y mtodos de una aplicacin. Utilizaremos comentarios Javadoc en nuestro cdigo fuente para que la documentacin de nuestras aplicaciones cuente con la misma organizacin y formato que el API de Java.

    Paquetes y el Estatuto import

    Las clases del API de Java estn agrupadas en paquetes. Un paquete es simplemente una coleccin de clases relacionadas. El siguiente es un ejemplo del nombre de un paquete:

    java.util

    El nombre completo calificado de una clase que es parte de un paquete es el nombre del paquete y el nombre de la clase, separados por un punto.

    java.util.GregorianCalendar

    Para declarar dos variables de tipo GregorianCalendar, podemos escribir:

    java.util.GregorianCalendar firstDate = new java.util.GregorianCalendar(2004, 1, 1); java.util.GregorianCalendar lastDate = new java.util.GregorianCalendar(2004, 12, 31);

    Escribir el nombre completo calificado de una clase es tedioso y el cdigo resultante es difcil de leer. Por esta razn, Java ofrece el estatuto import. Se utiliza para "importar" una clase o un paquete entero de clases en un archivo. Una clase importada puede ser referenciada utilizando su nombre simple, el nombre completo calificado menos el nombre del paquete. Un estatuto import est compuesto por la palabra clave import, un nombre completo calificado y un punto y coma:

  • import java.util.GregorianCalendar;

    Esta instruccin, colocada al inicio de un archivo, hace posible escribir:

    GregorianCalendar firstDate = new GregorianCalendar(2004, 1, 1); GregorianCalendar lastDate = new GregorianCalendar(2004, 12, 31);

    Esto resulta ms conveniente, debido a que el nombre del paquete debe ser mencionado slo una vez en el estatuto import. Continuamente, los programadores utilizan muchas clases del mismo paquete. En vez de utilizar un estatuto import para cada clase, se importa el paquete completo:

    import java.util.*;

    El asterisco (*) acta como un comodn, que representa a todas las clases del paquete especificado.

    El asterisco es conveniente. Por ejemplo, considera una aplicacin que utiliza el asterisco para importar todas las clases del paquete java.io, pero utiliza slo una. El nuevo cdigo que utilice otras clases de java.io puede ser agregado sin aadir ms estatutos import. Muchos programadores utilizan el asterisco, an cuando requieren slo una clase de un paquete, porque es rpido de escribir y no incurre en ninguna sobrecarga: importar un paquete no disminuye la velocidad de compilacin o ejecucin, ni incrementa el tamao del cdigo de bytes.

    Finalmente, el paquete java.lang es implcitamente importado en todas las aplicaciones de Java, de modo que nunca existe la necesidad de importar java.lang. Todas las aplicaciones pueden hacer referencia a clases del paquete java.lang utilizando sus nombres simples.

    Para cada una de las clases presentadas a continuacin, se te proporciona una liga a su documentacin API. Te alentamos a seguir estas ligas para que te familiarices con los muchos mtodos tiles que tienen estas clases.

    La Clase java.lang.String

    Debido a que Java no provee un tipo string primitivo, la clase java.lang.String se utiliza mucho. Java incluye la literal de la clase String, una secuencia de caracteres entre comillas dobles, tales como "abc". Una literal de la clase String es una instancia de la clase String.

    La siguiente es una lista de algunos mtodos definidos en la clase String:

    String(). Construye un nuevo objeto String que representa una secuencia vaca de caracteres.

    String(char[] value). Construye un nuevo objeto String que representa la secuencia de caracteres contenidos en el arreglo de caracteres.

  • String(String original). Construye un nuevo objeto String que representa la misma secuencia de caracteres que el argumento.

    int length(). Obtiene el nmero de caracteres en el String.

    char charAt(int index). Regresa el carcter que se encuentra en el ndice especificado.

    boolean equals(Object anObject). Regresa verdadero si anObject representa un String con la misma secuencia de caracteres.

    int indexOf(int ch). Regresa el ndice de la primera ocurrencia del carcter .

    int indexOf(String str). Regresa el ndice de la primera ocurrencia del String.

    boolean startsWith(String prefix). Verifica si el String tiene el prefijo especificado.

    String substring(int beginIndex, int endIndex). Regresa una subcadena.

    Java tambin provee el operador de concatenacin de String ( + ). Es un operador binario que requiere dos operandos de tipo String. Concatena estos operandos, regresando el resultado en un nuevo String. Las siguientes dos lneas representan objetos String equivalentes:

    "uno" + "dos" "unodos

    Observa que no se coloca ningn separador entre los operandos en el resultado

    Cada clase del API de Java tiene un mtodo llamado toString. Este mtodo regresa la representacin String de un objeto. Esto significa que cada instancia del API de Java tiene un String equivalente:

    "hola " + anyObject.toString()

    Convenientemente, si uno de los operandos del operador de concatenacin es un objeto (diferente de un String, por supuesto), el mtodo toString de dicho objeto ser invocado automticamente, permitiendo de este modo la concatenacin. Esto significa que podemos escribir:

    "hola " + anyObject

    Si un primitivo es el operando del operador de concatenacin String, ser reemplazado por un objeto equivalente y el mtodo toString de dicho objeto ser llamado. Esto significa que podemos escribir:

  • "hola " + 5

    Sin una traduccin automtica, tendramos que escribir:

    "hola " + (new Integer(5)).toString()

    Debido a que el smbolo ms ( + ) es tambin utilizado para sumar, por lo menos uno de sus operandos debe ser un String para que funcione como operador de concatenacin. Observa lo siguiente:

    stdOut.println(2 + 3 + "5"); // imprime 55, no 235 stdOut.println(2 + "" + 3 + "5"); // imprime 235

    El siguiente ejemplo ilustra el uso de mtodos en la clase String:

    El archivo StringClassDemo.java

    1: import java.io.*; // aqu est la clase PrintWriter 2: // no es necesario importar String porque se encuentra en java.lang 3: 4: /** 5: * Esta clase es una demostracin de la clase String 6: * 7: * @author 8: * version 1.0.0 9: */ 10: public class StringClassDemo { 11: 12: private static PrintWriter stdOut = new PrintWriter(System.out, true); 13: 14: /** 15: * Mtodo principal, muestra el uso de la clase String 16: * 17: * @param args no utilizados 18: */ 19: public static void main(String[] args) { 20: 21: String strHello = new String("Hello"); 22: 23: // la literal string ser reemplazado por el nuevo String("World") 24: String strWorld = "World"; 25: 26: // la concatenacin de cadenas imprime: Hello, World 27: stdOut.println(strHello + ", " + strWorld); 28: 29: // imprime el caracter r 30: stdOut.println(strWorld.charAt(2)); 31: 32: // imprime el entero 2 que es el ndice de la primera 'l' en strHello 33: stdOut.println(strHello.indexOf('l')); 34:

  • 35: // imprime el entero 1 que es el ndice del inicio de la cadena 36: // "or" en strWorld 37: stdOut.println(strWorld.indexOf("or")); 38: 39: // imprime el entero 6 que es el ndice de la primera 'o' en la 40: // cadena "HelloWorld" empezando por el ndice 5 41: stdOut.println((strHello + strWorld).indexOf('o', 5)); 42: 43: // imprime: "Hello" and "World" are equal in length 44: stdOut.print("\"" + strHello + "\" and \"" + strWorld + "\" are "); 45: if (strHello.length() != strWorld.length()) { 46: stdOut.print("not "); 47: } 48: stdOut.println("equal in length"); 49: 50: // re-asignar strWorld a un nuevo String podra 51: // imprimir: strWorld = "Hello"; 52: strWorld = new String("Hello"); 53: 54: // aqu no se imprime nada 55: // Esto puede ser sorprendente, pero recuerda, debido a que los 56: // Strings son objetos, el == compara las direcciones 57: // de los objetos, no los objetos en s. 58: if (strHello == strWorld) { 59: stdOut.println("The strings are equivalent according to =="); 60: } 61: 62: // a continuacin se presenta lo que debe escribirse 63: // imprime: The strings are equivalent. 64: if (strHello.equals(strWorld)) { 65: stdOut.println("The strings are equivalent."); 66: } 67: 68: // existe un grupo de mtodos estadsticos para convertir de 69: // un primitivo a una representacin String del mismo 70: String strValues; 71: 72: strValues = String.valueOf(5.87); // strValues es ahora "5.87" 73: strValues = String.valueOf(true); // strValues es ahora "true" 74: strValues = String.valueOf(18); // strValues es ahora "18" 75: 76: // concatenacin 77: stdOut.println(5.87 + "" + true + "" + 18); // imprime 5.87true18 78: } 79: }

    La Clase java.util.StringTokenizer

    Tokenizacin (tokenizing) es el proceso de descomponer una cadena en piezas ms pequeas llamadas tokens. Los tokens estn separados, o delimitados, por un carcter o un grupo de caracteres. Por ejemplo, si consideramos que la siguiente cadena es tokenizada utilizando espacios en blanco como delimitador, el resultado sera cinco tokens:

  • "Esta cadena tiene cinco tokens"

    El espacio en blanco es el delimitador ms comn (espacio en blanco incluye el carcter de espacio, el carcter tabulador, el carcter de nueva lnea, y el carcter retorno de carro). Otros delimitadores de uso frecuente son el guin bajo ( _ ) y la coma ( , ).

    "Esta_cadena_tiene_cinco_tokens" "Esta,cadena,tiene,cinco,tokens"

    Cualquier carcter puede usarse como delimitador. Por ejemplo, si la cadena "Esta cadena tiene cinco tokens" es tokenizada utilizando el carcter "n" como delimitador, el resultado ser cinco tokens:

    "Esta cade" "a tie" "e ci" "co toke" "s"

    Sin embargo, los delimitadores tales como "n", son poco comunes.

    La clase StringTokenizer es parte del paquete java.util. La siguiente, es una lista de algunos de los mtodos de la clase StringTokenizer:

    StringTokenizer(String str). Construye un tokenizador de cadenas. Utiliza el delimitador predeterminado, el espacio en blanco.

    StringTokenizer(String str, String delim). Construye un tokenizador de cadenas. El argumento delim contiene los caracteres delimitadores para separar los tokens.

    boolean hasMoreTokens(). Verifica si hay ms tokens que extraer.

    String nextToken(String delim). Regresa el siguiente token de la cadena.

    int countTokens(). Obtiene el nmero de tokens que an pueden ser extrados, no el nmero de tokens de la cadena.

    La siguiente aplicacin almacena los datos del inventario de un producto (nombre, cantidad y precio) en un String. El String est delimitado por el carcter de guin bajo ( _ ). La aplicacin utiliza un objeto StringTokenizer para extraer los tokens del String.

    1: 2: 3: 4: 5: 6:

    import java.util.*; public class ProductInfo { public static void main(String[] args) {

  • 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:

    String data = "Mini Discs 74 Minute (10-Pack)_5_9.00"; StringTokenizer tknzr = new StringTokenizer(data, "_"); String name = tknzr.nextToken(); String quantity = tknzr.nextToken(); String price = tknzr.nextToken(); System.out.println("Name: " + name); System.out.println("Quantity: " + quantity); System.out.println("Price: " + price); } }

    Listado 1 ProductInfo.java

    Cuando la aplicacin es ejecutada, los datos del inventario son desplegados.

    Figura 1 Ejecucin de ProductInfo

    El siguiente ejemplo ilustra el uso de la clase StringTokenizer.

    El archivo StringTokenizerClassDemo.java

    1: import java.io.*; // la clase PrintWriter est aqu 2: import java.util.*; // la clase StringTokenizer est aqu 3: 4: 5: /** 6: * Esta clase es una demostracin de la clase StringTokenizer 7: * 8: * @author 9: * version 1.0.0 10: */ 11: public class StringTokenizerClassDemo { 12: 13: private static PrintWriter stdOut = new PrintWriter(System.out, true); 14: 15: /** 16: * Mtodo principal, muestra el uso de la clase StringTokenizer 17: * 18: * @param args no utilizado 19: */

  • 20: public static void main(String[] args) { 21: 22: String str = "This string has five tokens"; 23: 24: // el delimitador predeterminado es la cadena "\t\n\r\f", 25: // por ejemplo, espacio en blanco 26: StringTokenizer tokenizer = new StringTokenizer(str); 27: 28: 29: stdOut.println("The input string: " + str); 30: stdOut.println(); // imprime una lnea en blanco 31: 32: // el siguiente bucle imprime cada palabra de la cadena, 33: // una por lnea 34: stdOut.println("The input string tokenized by " + 35: "the default delimiter (whitespace):"); 36: 37: int i = 1; 38: 39: while (tokenizer.hasMoreTokens()) { 40: stdOut.println("Token #" + i + ": " + tokenizer.nextToken()); 41: ++i; 42: } 43: 44: stdOut.println(); // imprime una lnea en blanco 45: 46: // el delimitador puede ser especificado como una 47: // cadena utilizando el siguiente constructor 48: tokenizer = new StringTokenizer(str, "i"); 49: 50: 51: // este bucle imprimir las cuatro cadenas "Th", 52: // "s str", "ng has f", "ve tokens", una por lnea 53: stdOut.println("The input string tokenized by \"i\":"); 54: i = 1; 55: while (tokenizer.hasMoreTokens()) { 56: stdOut.println("Token #" + i + ": " + tokenizer.nextToken()); 57: ++i; 58: } 59: } 60: }

    Las Clases de Envoltura (Wrapper Classes)

    Existen muchas clases en el API de Java y los programadores pueden definir an muchas ms. Sin embargo, slo se tienen disponibles unos cuantos primitivos. En ciertos aspectos, sera deseable que en los programas de Java pudiramos tratar todos los datos de la misma manera consistente. Para hacer esto realidad, Java cuenta con clases que simulan a los tipos primitivos. Para cada tipo primitivo existe una de estas clases. Estas clases constituyen en conjunto las clases de envoltura:

    java.lang.Byte

  • java.lang.Short java.lang.Integer java.lang.Long java.lang.Character java.lang.Float java.lang.Double java.lang.Boolean

    Observe que los nombres de las clases de envoltura son muy similares a los nombres de sus contrapartes primitivos. Una clase de envoltura contiene un campo simple cuyo tipo es el primitivo correspondiente. Por ejemplo, la clase Integer contiene un campo de tipo int. La siguiente aplicacin ilustra el uso de la clase de envoltura Integer.

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:

    public class WrapperConversion { public static void main(String[] args) { Integer objectValue = new Integer(100); int intValue = objectValue.intValue(); long longValue = objectValue.longValue(); double doubleValue = objectValue.doubleValue(); String stringValue = objectValue.toString(); System.out.println("objectValue: " + objectValue); System.out.println("intValue: " + intValue); System.out.println("longValue: " + longValue); System.out.println("doubleValue: " + doubleValue); System.out.println("stringValue: " + stringValue); } }

    Listado 2 WrapperConversion.java

    Las clases de envoltura son parte del paquete java.lang y por lo tanto no necesita ser importado explcitamente. La aplicacin crea un objeto de envoltura para almacenar un entero y despus encuentra los valores long, double y String equivalentes. La siguiente figura muestra el resultado de la ejecucin de WrapperConversion:

    Figura 2 Ejecucin de WrapperConversion

    Adems, las clases de envoltura proveen mtodos para convertir tipos primitivos a objetos String y objetos String a tipos primitivos. Por ejemplo, Integer.toString(10)

  • convierte el valor entero 10 en el String "10" e Integer.parseInt("10") convierte el String "10" al valor entero 10.

    Podemos mejorar la aplicacin ProductInfo. El mtodo nextToken regresa un String, que no es muy til cuando el token que ser extrado es un valor numrico como cantidad o precio. Podemos utilizar la clase Integer para convertir el String que contiene la cantidad en un valor entero; podemos usar la clase Double para convertir el String que contiene el precio en un valor real (double). Ahora es posible calcular el valor total del producto.

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:

    import java.util.*; public class ProductValue { public static void main(String[] args) { String data = "Mini Discs 74 Minute (10-Pack)_5_9.00"; StringTokenizer tokenizer = new StringTokenizer(data, "_"); String name = tokenizer.nextToken(); int quantity = Integer.parseInt(tokenizer.nextToken()); double price = Double.parseDouble(tokenizer.nextToken()); System.out.println("Name: " + name); System.out.println("Quantity: " + quantity); System.out.println("Price: " + price); System.out.println("Total: "+ quantity * price); } }

    Listado 3 ProductValue.java

    La siguiente figura muestra el resultado de la ejecucin de ProductValue:

    Figura 3 Ejecucin de ProductValue

  • 1.1.4 Consola E/S (I/O) El Paquete java.io Leyendo Valores Primitivos

    El Paquete java.io

    El paquete java.io tiene una gran cantidad de clases. Sin embargo, aqu slo estudiaremos dos de ellas. La clase java.io.BufferedReader se utiliza para entrada. La clase java.io.PrintWriter se utiliza para salida.

    La siguiente es una plantilla para las clases que utilizan la consola E/S (entrada/salida):

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:

    import java.io.*; // contains BufferedReader and PrintWriter public class AnyClassUsingIO { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdOut = new PrintWriter(System.out, true); private static PrintWriter stdErr = new PrintWriter(System.err, true); /* other variables */ /* methods */ }

    Listado 1 Plantilla de una clase que utiliza ES

    El modificador private lo estudiaremos posteriormente. En pocas palabras, este modificador no permite que otras clases utilicen las variables stdIn, stdOut y stdErr.

    System.in es el flujo de entrada "estndar". Tpicamente, este flujo corresponde a la entrada del teclado.

    System.out es el flujo de salida "estndar". Tpicamente, este flujo corresponde a la salida en pantalla.

    System.err es el flujo de salida de "error". Tpicamente, este flujo corresponde a la salida en pantalla.

    System.out se utiliza para desplegar la salida tpica y normal de los programas. System.err se usa para mostrar avisos y mensajes de error al usuario. Esto es slo una convencin que facilita tanto a los programadores como a los usuarios identificar los diferentes tipos de salida.

  • System.out y System.err pudieran usarse para salida por s mismos. Sin embargo, es ms conveniente incluir cada uno de ellos en un objeto PrintWriter. La clase PrintWriter ofrece dos mtodos para imprimir: println y print. El primero agrega automticamente un rengln a la salida, mientras que el segundo no lo hace. Los mtodos println y print pueden tener muchos tipos de argumentos. Consideremos el siguiente ejemplo que utiliza println:

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:

    import java.io.*; public class PrintlnDemo { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdOut = new PrintWriter(System.out, true); private static PrintWriter stdErr = new PrintWriter(System.err, true); public static void main(String[] args) { stdOut.println("A line of output."); stdOut.println(5); stdOut.println(7.27); stdOut.println(true); stdOut.println(); } }

    Listado 2 PrintlnDemo.java

    A continuacin se muestra la salida de PrintlnDemo:

    Figura 1 Ejecucin de PrintlnDemo

    Compara la salida de PrintlnDemo con la salida de PrintDemo, una clase que utiliza print:

    1: 2: 3: 4:

    import java.io.*; public class PrintDemo {

  • 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:

    private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdOut = new PrintWriter(System.out, true); private static PrintWriter stdErr = new PrintWriter(System.err, true); public static void main(String[] args) { stdOut.print("A line of output."); stdOut.print(5); stdOut.print(7.27); stdOut.print(true); stdOut.println(); } }

    Listado 3 PrintDemo.java

    A continuacin se presenta la salida de PrintDemo:

    Figura 2 Ejecucin de PrintDemo

    El operador de concatenacin String se utiliza frecuentemente para construir argumentos para println y print:

    stdOut.println("El nmero cinco: " + 5);

    El segundo argumento del constructor PrintWriter es un booleano que indica si debe o no realizarse un vaciado (flushing) automtico. Cuando un programa produce salida para la pantalla, esta salida no va directamente a la pantalla. Primero va a un rea de retencin llamada bfer (buffer). Este bfer es vaciado en forma automtica cuando se llena y enva sus contenidos directamente a la pantalla. Sin embargo, en la mayora de los casos las instrucciones de salida no llenan el bfer y por lo tanto su salida permanece en el bfer en vez de ser desplegada en pantalla. Puesto que es ms natural para el programador que la salida ocurra inmediatamente, la clase PrintWriter cuenta con una caracterstica de vaciado opcional y automtica llamada autovaciado (auto-flush). Cuando el segundo argumento para el constructor PrintWriter es verdadero, se habilita el autovaciado y el bfer es vaciado automticamente despus de cada llamada al mtodo printlnpero no despus de las llamadas al mtodo print. El programador puede utilizar el mtodo flush

  • para vaciar el bfer despus de una llamada al mtodo print. El siguiente ejemplo ilustra el uso del mtodo flush:

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:

    import java.io.*; public class Hello { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdOut = new PrintWriter(System.out, true); private static PrintWriter stdErr = new PrintWriter(System.err, true); public static void main(String[] args) throws IOException { stdErr.print("Please enter you name on this line: "); stdErr.flush(); String input = stdIn.readLine(); stdOut.println("Hello " + input); } }

    Listado 4 Hello.java

    La excepcin IOException ser estudiada en la pgina Objetos Excepcin. Observa que stdErr, el flujo de salida estndar, se utiliza para desplegar mensajes. Si la llamada al mtodo print que genera la salida del mensaje no es seguido por una llamada al mtodo flush, el usuario probablemente no ver el mensaje adecuadamente. Usualmente, esto no es deseable.

    Para manejar las entradas, System.in puede usarse por s solo, pero sus capacidades son limitadas ya que nicamente puede leer un carcter a la vez. Esto resultara fastidioso cuando queremos leer toda una lnea de entrada. Encerrando System.in en un objeto BufferedReader posibilita la lectura de lneas completas de entrada. El mtodo BufferedReader empleado para este fin es readLine.

    Una llamada al mtodo readLine ocasiona que el programa se detenga o que se bloquee hasta que el usuario escriba una lnea de informacin. Cuando el usuario presiona la tecla ENTER, la lnea es leda por el mtodo readLine y se regresa como String.

    A continuacin se presenta la salida de Hello:

  • Figura 3 Ejecucin de Hello

    Leyendo Valores Primitivos

    No siempre deseamos que la entrada sea un String. Por ejemplo, en un programa podemos pedir que se escriba un entero. Puede extraerse un entero de la entrada utilizando un mtodo de las clases de envoltura (wrapper classes) para enteros. La siguiente lnea de cdigo ilustra cmo se realiza esto:

    int value = Integer.parseInt(stdIn.readLine());

    Utilizando el mtodo esttico parseInt de la clase Integer, la entrada, leda como un String, es convertida a int de manera que sta pueda ser guardada en una variable int. La mayora de las clases de envoltura tienen un mtodo similar para convertir (parse) una cadena de caracteres: la clase Double tiene el mtodo parseDouble, mientras que la clase Float cuenta con el mtodo parseFloat. La excepcin es la clase Boolean, que utiliza el mtodo getBoolean. Para extraer un carcter de la entrada, se debe utilizar el mtodo charAt para obtener el carcter en el String regresado por el mtodo readline. O bien, se puede utilizar el mtodo read en vez del mtodo readLine. Sin embargo, si se desea utilizar el mtodo read se requiere convertir el tipo (cast) antes de hacer la asignacin debido a que el mtodo read regresa un int, no un char.

    La siguiente clase utiliza un objeto StringTokenizer para leer tres enteros a partir de una lnea de entrada:

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:

    import java.io.*; import java.util.*; public class ReadThreeIntegers { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdOut = new PrintWriter(System.out, true); private static PrintWriter stdErr = new PrintWriter(System.err, true); public static void main(String[] args) throws IOException {

  • 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:

    stdErr.print("Enter three integers on one line: "); stdErr.flush(); StringTokenizer tokenizer = new StringTokenizer(stdIn.readLine()); if (tokenizer.countTokens() != 3) { stdErr.println("Invalid input"); } else { int firstValue = Integer.parseInt(tokenizer.nextToken()); int secondValue = Integer.parseInt(tokenizer.nextToken()); int thirdValue = Integer.parseInt(tokenizer.nextToken()); stdOut.println("First value: " + firstValue); stdOut.println("Second value: " + secondValue); stdOut.println("Third value: " + thirdValue); } } }

    Listado 5 ReadThreeIntegers.java

    A continuacin se presenta la salida de ReadThreeIntegers:

    Figura 4 Ejecucin de ReadThreeIntegers

  • 1.1.5 Objetos Excepcin Manejo de Excepciones Objetos Excepcin Clases de Excepciones Excepciones Definidas por el Usuario El Bloque try-catch La Clusula throws La Instruccin throw Documentando Excepciones con Javadoc

    Lecturas:

    Requeridas: o Barker, primera edicin, captulo 13 (pginas 3202). o Barker, segunda edicin, captulo 13 (pginas 473

    501).

    Secuencia: Leer el libro de texto antes de leer esta pgina.

    Manejo de Excepciones

    Un cdigo robusto es un cdigo que responde apropiadamente a entradas invlidas y condiciones ambientales inesperadas. Durante la ejecucin de un programa pueden ocurrir muchas fallas o eventos excepcionales que interrumpen el flujo normal de un programa. Por ejemplo, un programa puede tratar de abrir un archivo que no existe o dividir un nmero entre cero. Un cdigo robusto maneja adecuadamente las fallas: contina la ejecucin a pesar del problema o termina la ejecucin despus de desplegar un mensaje de error.

    En la programacin tradicional, debes incluir instrucciones condicionales para detectar y manejar fallas en los programas. Frecuentemente, este cdigo es difcil de leer y mantener. Por ejemplo, el siguiente es el pseudocdigo de un mtodo que lee un entero a partir de la entrada estndar.

    int readInteger () { Lee una cadena de la entrada estndar Convierte la cadena en un valor entero Regresa el valor entero }

    Este pseudocdigo ignora las fallas que puedan ocurrir:

    La cadena de caracteres no puede ser leda de la entrada estndar. Por ejemplo, la entrada estndar puede ser un archivo daado.

  • La cadena de caracteres no contiene un entero. Por ejemplo, el usuario puede introducir "2r" en vez de "25".

    Para hacer que tu mtodo sea robusto, debes aadir cdigo para detectar y manejar las fallas potenciales:

    int readInteger () { while (true) { lee una cadena de la entrada estndar; if (la lectura de la entrada estndar falla) { maneja el error de la entrada estndar; } else { convierte la cadena en un valor entero; if (la cadena no contiene un entero) { maneja el error de formato de nmero invlido; } else { regresa el valor entero; } } } }

    El manejo de excepciones es un mecanismo que permite que las fallas sean manejadas fuera del flujo normal del cdigo. El cdigo resultante es claro, fcil de leer y fcil de mantener. El siguiente es un pseudocdigo que utiliza manejo de excepciones:

    int readInteger () { while (true) { try { lee una cadena a partir de la entrada estndar; convierte la cadena en un valor entero; regresa el valor entero; } catch (la lectura de la entrada estndar fall) { maneja el error de entrada estndar; } catch (la cadena no contiene un entero) { maneja el error de formato de nmero invlido; } } }

    Con el manejo de excepciones, el flujo normal del cdigo es especificado en el cuerpo de un bloque try y cada falla es manejada en un bloque catch que se encuentra separado del flujo normal del cdigo.

    Objetos Excepcin

    En Java, una excepcin es un objeto que describe una situacin anormal. Un objeto excepcin (exception object) contiene la siguiente informacin:

    El tipo de excepcin Una pila de llamadas (call stack) que indica donde ocurri la excepcin

  • Una cadena de caracteres con informacin adicional sobre la excepcin

    Cuando ocurre una situacin anormal, un mtodo puede crear un objeto excepcin y despus lanzarlo (throw). Si el mtodo que hace la llamada no est preparado para atrapar (catch) el objeto excepcin, ste lanza el objeto excepcin al mtodo que lo llama y as sucesivamente. El objeto excepcin pasa a travs de la secuencia de mtodos que han sido llamados (la pila de llamadas) hasta que es atrapado. El mtodo que atrapa el objeto excepcin utiliza la informacin que se encuentra en el objeto para manejar la excepcin.

    Cuando un mtodo lanza una excepcin, ninguna de las instrucciones restantes en dicho mtodo son ejecutadas. Si ninguno de los mtodos de la pila de llamadas atrapa la excepcin y el mtodo que se encuentra en cima de la pila es main, el programa despliega, en el flujo de error estndar, un mensaje que identifica la excepcin y finaliza. Para prevenir la terminacin prematura de un programa, debes incluir bloques try-catch que permitan que el programa se recupere de las fallas.

    La siguiente figura ilustra cmo se lanzan y se atrapan las excepciones.

    Figura 1 Lanzando y atrapando un objeto de excepcin

  • La siguiente clase contiene el cdigo de la secuencia de eventos ilustrada en la Figura 1. (Las instrucciones que crean excepciones y que las manejan sern descritas posteriormente en esta pgina).

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:

    /** * Esta clase demuestra cmo se lanzan y se atrapan excepciones. * * @author * @version 1.0.0 */ public class ExceptionDemo { /** * Llama a methodA * * @param args no utilizado */ public static void main(String[] args) { methodA(); System.out.println("MethodA passed"); } /** * Llama a methodB. Si ocurre una excepcin; la atrapa, reporta el * error y termina el programa. */ public static void methodA() { try { methodB(); System.out.println("MethodB passed"); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } /** * Llama a methodC. Si ocurre una excepcin, la lanza al mtodo que * hizo la llamada. * * @throws Exception cuando methodC es llamado. */ public static void methodB() throws Exception { methodC(); System.out.println("MethodC passed"); } /** * Llama a methodD. Si ocurre una excepcin, la lanza al mtodo que

  • 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69:

    * hizo la llamada. * * @throws Exception cuando ethodD es llamado. */ public static void methodC() throws Exception { methodD(); System.out.println("MethodD passed"); } /** * Lanza una excepcin * * @throws Exception cada vez que methodD es llamado. */ public static void methodD() throws Exception { throw new Exception("This is an Exception Message"); } }

    Listado 1 ExceptionDemo.java

    En la clase ExceptionDemo, el mtodo main llama a methodA, methodA llama a methodB, methodB llama a methodC y methodC llama a methodD. El ltimo mtodo de la secuencia, methodD, crea un nuevo objeto de excepcin y lo lanza al methodC. La excepcin pasa por methodC y methodB hasta que es atrapado por methodA. methodA maneja la excepcin imprimiendo un rastro de la pila y terminando el programa. El rastro de la pila muestra la secuencia de mtodos que fueron llamados antes de que la excepcin fuera lanzada. La siguiente figura muestra la consola de salida al ejecutar ExceptionDemo:

    Figura 2 Ejecucin de ExceptionDemo.java

    La consola despliega la informacin almacenada en el objeto Exception. Esta informacin contiene:

    El nombre de la excepcin: java.lang.Exception El mensaje de la excepcin: This is an Exception Message El rastro de la pila (stack trace), el cual es muy til al depurar las excepciones.

    Muestra la secuencia de mtodos que fueron llamados antes de que la excepcin fuera lanzada.

  • Observa que las instrucciones de imprimir que se encuentran en methodB y methodC nunca fueron ejecutadas.

    Los objetos excepcin cuentan con un grupo de mtodos comunes. Incluyen:

    String getMessage(). Obtiene el argumento que fue pasado al constructor del objeto de excepcin.

    String toString(). El nombre de la excepcin (su tipo), seguido por dos puntos ( : ), seguidos por el String regresado por el mtodo getMessage.

    void printStackTrace(). Este mtodo despliega, en el flujo de error estndar, el String regresado por el mtodo toString, seguido por la informacin que muestra dnde fue lanzada la excepcin. La informacin incluye una lista de todos los mtodos que fueron llamados antes de que ocurriera la excepcin.

    Clases de Excepciones

    Los objetos excepcin son instancias de clases que descienden de la clase Throwable. Throwable tiene dos subclases: Error y Exception.

    La clase Error es utilizada para problemas serios, donde es poco probable que una aplicacin se recupere. Un ejemplo es el error "out of memory" (sin memoria).

    La clase Exception es utilizada para las condiciones anormales que una aplicacin puede esperar que sean manejadas.

    Java divide las excepciones en dos categoras: las excepciones verificadas (checked exceptions) y las excepciones no verificadas (unchecked exceptions). Las excepciones que no son "verificadas" por el compilador son llamadas excepciones no verificadas; las excepciones que son "verificadas" por el compilador, son llamadas excepciones verificadas. El compilador no compilar un archivo si contiene un mtodo donde pueda ocurrir una excepcin verificada y el mtodo no maneje la excepcin verificada en un bloque catch o lo enliste en el encabezado del mtodo. Las clases RuntimeException, Error y sus subclases son excepciones no verificadas. Todas las dems clases de excepcin son excepciones verificadas.

  • Figura 3 Jerarqua de excepciones

    Excepciones Definidas por el Usuario

    Puede definirse nueva clase de excepcin verificada extendiendo la clase Exception; una nueva clase de excepcin no verificada puede definirse extendiendo la clase RuntimeException. La siguiente clase define una excepcin verificada para un error fuera de rango:

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:

    /** * Lanzada cuando ocurre un error fuera de rango. * * @author nombre del autor * @version 1.0.0 */ public class OutOfRangeException extends Exception { /** * Construye una nueva instancia de OutOfRangeException. */ public OutOfRangeException() { } /** * Construye una nueva instancia de OutOfRangeException * que incluye una explicacin. * * @param message Informacin adicional sobre esta excepcin. * Puede ser nulo. */ public OutOfRangeException(String message) { super(message); } }

    Listado 2 OutOfRangeException.java

  • El segundo constructor es utilizado cuando hay informacin disponible sobre la excepcin.

    El Bloque try-catch

    Si un mtodo elige manejar una excepcin, debe tener un bloque try-catch. Un bloque try delimita el cdigo que puede lanzar una excepcin. Un bloque try tiene el siguiente aspecto:

    try { // cdigo que puede lanzar excepciones }

    A un bloque try le siguen uno o ms bloques catch. Un bloque catch tiene el siguiente aspecto:

    catch (TipoExcepcin e) { // cdigo que maneja la excepcin }

    TipoExcepcin es el tipo, o el nombre de la clase de la excepcin que el bloque catch manejar. Observa que un bloque catch se parece a un encabezado de mtodo porque toma un argumento.

    Pueden aparecer muchos bloques catch despus de un bloque try, cada uno atrapando una excepcin diferente. Cuando se lanza una excepcin, cada bloque catch es examinado, comenzando con el bloque catch que se encuentra inmediatamente despus del bloque try. El tipo de la excepcin lanzada es comparado con el tipo del argumento del bloque catch. Cuando encuentra una coincidencia, es ejecutado el cuerpo del bloque catch que coincide. Entonces, la ejecucin sigue despus del ltimo bloque catch. Si ningn bloque catch coincide, la excepcin se deja pasar a la pila de llamadas.

    Considera el siguiente cdigo. La clase IntegerReader tiene un mtodo llamado readInteger que lee un entero de la entrada estndar:

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:

    import java.io.*; /** * Esta clase provee un mtodo que lee un entero de la * entrada estndar. * * @author * @version 1.0.0 */ public class IntegerReader { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdErr =

  • 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55:

    new PrintWriter(System.err, true); private static PrintWriter stdOut = new PrintWriter(System.err, true); /** * Prueba el mtodo readInteger. * * @param args no utilizado. */ public static void main (String[] args) { stdOut.println("The value is: " + readInteger()); } /** * Lee un entero de la entrada estndar. * * @return regresa el valor int. */ public static int readInteger() { do { try { stdErr.print("Enter an integer > "); stdErr.flush(); return Integer.parseInt(stdIn.readLine()); } catch (IOException ioe) { ioe.printStackTrace(); System.exit(1); // Termina el programa } catch (NumberFormatException nfe) { stdErr.println("Invalid number format"); } } while (true); } }

    Listado 3 IntegerReader.java

    El mtodo BufferedReader.readLine que se encuentra en la lnea 43 puede lanzar una excepcin de tipo IOException. El bloque catch de la lnea 45 maneja la excepcin IOException desplegando, en el flujo de error estndar, la pila de llamadas y terminando el programa. El mtodo Integer.parseInt de la lnea 43 puede lanzar una excepcin de tipo NumberFormatException. El bloque catch de la lnea 50 maneja la excepcin NumberFormatException desplegando, en el flujo de error estndar, el mensaje "Invalid number format" y la ejecucin contina; es decir, se le da otra oportunidad al usuario de introducir un entero.

    El argumento de un bloque catch puede ser engaoso. Por ejemplo, el siguiente bloque catch atrapar una excepcin IOException; tambin atrapar una excepcin

  • FileNotFoundException y una EOFException porque las clases FileNotFoundException y EOFException son subclases de la clase IOException. Ver Figura 3.

    catch (IOException e) { // cdigo para manejar IOException, FileNotFoundException y EOFException }

    La Clusula throws

    Si una excepcin verificada puede ocurrir en un mtodo y dicho mtodo no tiene un bloque catch para manejar la excepcin verificada, entonces sta debe ser declarada en el encabezado del mtodo utilizando una clusula throws. Por ejemplo, si puede ocurrir una excepcin de tipo IOException en un mtodo readInteger y readInteger no lo maneja, entonces readInteger debe tener el siguiente encabezado:

    public int readInteger() throws IOException { }

    Si el mtodo readInteger no enlista IOException en su clusula throws, la compilacin fallar y presentar un error sobre las excepciones verificadas. Las excepciones no verificadas pueden ser enlistadas en una clusula throws, pero el compilador no lo requiere.

    En el siguiente cdigo, ni el mtodo readInteger ni el mtodo main( ) atrapan la excepcin IOException; por lo tanto, ambos declaran IOException en sus clusulas throws. Cuando un mtodo main lanza una excepcin IOException, el objeto de excepcin es pasado a la Mquina Virtual de Java (Java Virtual Machine o JVM). La JVM despliega la informacin de la excepcin y termina el programa.

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:

    import java.io.*; /** * Esta clase provee un mtodo que lee un entero de la * entrada estndar. * * @author * @version 1.0.0 */ public class IntegerReaderThrowsException { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdErr = new PrintWriter(System.err, true);

  • 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:

    private static PrintWriter stdOut = new PrintWriter(System.err, true); /** * Prueba el mtodo readInteger * * @param args no utilizado * @throws IOException si hay error al leer de la entrada estndar. */ public static void main (String[] args) throws IOException { stdOut.println("The value is: " + readInteger()); } /** * Lee un entero de la entrada estndar. * * @return regresa el valor int. * @throws IOException si hay error al leer de la entrada estndar. */ public static int readInteger() throws IOException { do { try { stdErr.print("Enter an integer> "); stdErr.flush(); return Integer.parseInt(stdIn.readLine()); } catch (NumberFormatException nfe) { stdErr.println("Invalid number format"); } } while (true); } }

    Listado 4 IntegerReaderThrowsException.java

    La Instruccin throw

    Los mtodos definidos por el usuario tambin pueden lanzar excepciones. Para lanzar una excepcin, utilizan la palabra clave throw, seguida por un objeto excepcin. Por ejemplo:

    throw new OutOfRangeException();

    El objeto excepcin es creado como cualquier otro objeto, utilizando el operador new y un constructor. La siguiente sentencia utiliza el constructor de la excepcin OutOfRangeException que acepta un argumento de tipo String.

    throw new OutOfRangeException("Not a valid number");

  • Considera la clase PositiveInteger que envuelve un valor entero positivo. Tiene un constructor y mtodos para inspeccionar y modificar el valor entero positivo.

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:

    import java.io.*; /** * Envuelve un valor entero positivo. * * @author * @version 1.0.0 */ public class PositiveInteger { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdErr = new PrintWriter(System.err, true); private static PrintWriter stdOut = new PrintWriter(System.err, true); private int value; /** * Prueba el mtodo readInteger * * @param args no utilizado * @throws IOException si hay error al leer de la entrada estndar. */ public static void main(String[] args) throws IOException { PositiveInteger object; do { try { stdErr.print("Enter an integer> "); stdErr.flush(); int value = Integer.parseInt(stdIn.readLine()); object = new PositiveInteger(value); break; } catch (NumberFormatException nfe) { stdErr.println("Invalid number format"); } catch (OutOfRangeException ore) { stdErr.println(ore.getMessage()); } } while (true); stdOut.println("The value is: " + object.getValue()); } /**

  • 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96:

    * Construye un objeto PositiveInteger con el * valor especificado por el argumento. * * @param initialValue un entero. El valor debe ser positivo. * @throws OutOfRangeException si el valor es negativo. */ private PositiveInteger(int initialValue) throws OutOfRangeException { if (initialValue < 0) { throw new OutOfRangeException("Number not positive"); } else { this.value = initialValue; } } /** * Regresa el nmero positivo * * @return regresa el valor */ public int getValue() { return this.value; } /** * Modifica el nmero positivo. * * @param newValue el nuevo entero. El valor debe ser positivo. * @throws OutOfRangeException si el nuevo valor es negativo. */ private void setValue (int newValue) throws OutOfRangeException { if (newValue < 0) { throw new OutOfRangeException("Number not positive"); } else { this.value = newValue; } } }

    Listado 5 PositiveInteger.java

    En esta clase, tanto el constructor como el mtodo setValue crean y lanzan una excepcin de tipo OutOfRangeException cuando el valor del argumento no es positivo (lneas 59 y 86). Observa que la excepcin OutOfRangeException es atrapada en el mtodo main que se encuentra en la lnea 44.

    Documentando Excepciones con Javadoc

  • La etiqueta Javadoc para una excepcin es la etiqueta @throws tambin puede emplearse la etiqueta @exception. El comentario Javadoc para un mtodo debe tener una etiqueta @throws por cada excepcin verificada que el mtodo pudiera lanzar. Tambin puede tener etiquetas @throws para las excepciones no verificadas, pero no es necesario. El comentario Javadoc no debe tener una etiqueta @throws para las excepciones atrapadas y manejadas por el mtodo. Utiliza los siguientes lineamientos para documentar excepciones:

    Cuando el mtodo lanza ms de una excepcin, cada excepcin debe estar documentada en una lnea diferente y debe ser enlistada alfabticamente.

    Ubica las etiquetas @throws despus de las etiquetas @param y @return. Las etiquetas @throws deben describir la(s) situacin(es) que causarn la excepcin.

  • 1.1.6 Convenciones de Cdigo

    Lecturas:

    Requerida: o Software de Java, Sun Microsystems, Inc, Code

    Conventions for the Java Programming Language (Convenciones de Cdigo para el Lenguaje de Programacin Java). Este documento contiene las convenciones estndar que Sun Microsystems sigue y recomienda a los dems. Cubre nombres de archivos, organizacin de archivos, sangrado del cdigo, comentarios, declaraciones, instrucciones, espacios en blanco, convenciones de nombres y prcticas de programacin. Tambin incluye un ejemplo de cdigo.

    Uno de los objetivos de este curso es que aprendas a utilizar un buen estilo de programacin. Un buen estilo de programacin es un componente importante de la prctica profesional de desarrollo de software.

    El producto de tu trabajo profesional de programacin ser tu cdigo fuente. Al igual que cualquier otro producto comercial, debes asegurarte de que tu cdigo tiene la mayor calidad posible.

    Tu cdigo existir por un tiempo largo. Debes asegurarte que tu cdigo sea legible y fcil de entender para los dems. Un cdigo difcil de entender podra ser descartado y reescrito.

    Como parte de un equipo de desarrollo, debes esforzarte por lograr la consistencia de entre tu cdigo y el cdigo de tus compaeros de equipo.

    Tu estilo de programacin generalmente refleja el tipo de programador que eres. Un cdigo claro y bien organizado usualmente refleja un programador bien organizado y con ideas claras.

    Adems, un buen estilo de programacin hace el cdigo ms fcil de rastrear, depurar y clasificar. Existen muchas opiniones diferentes sobre lo que constituye un buen estilo. Cada organizacin definir sus propias convenciones de cdigo. Sin embargo, es posible definir algunos principios bsicos:

    Las convenciones de cdigo deben asegurar que la estructura lgica del cdigo es fcil de seguir. Por ejemplo, las instrucciones en el cuerpo de un bucle deben sangrarse un nivel.

  • Las convenciones de cdigo deben mejorar la legibilidad. Por ejemplo, el nombre de los identificadores debe seguir las convenciones de nombres para que sea fcil reconocer las constantes, las clases, los mtodos y las variables.

    Las convenciones de cdigo deben prevenir la introduccin de errores accidentales. Por ejemplo, las llaves deben delimitar el cuerpo de un bucle an cuando el cuerpo contenga una sola instruccin. Esto previene el error lgico que ocurre cuando un programador aade una instruccin al cuerpo del bucle sin agregar un conjunto de llaves.

    La eleccin de un conjunto de convenciones sobre otra puede parecer completamente arbitraria. Elegimos utilizar las convenciones de cdigo de Sun porque son reconocidas por una comunidad muy grande de desarrolladores profesionales.

    Como nota final, las convenciones de cdigo no deben ser aplicadas despus de escribir tu cdigo. El nombre de una variable debe seguir la convencin de nombres al ser definido. Una lnea de cdigo debe una sangra apropiada al momento de ser escrita. Una estructura de control nunca debe escribirse sin llaves. Esto representa trabajo extra al principio, pero en realidad es tiempo bien gastado porque tu cdigo ser mucho ms fcil de depurar!

  • 1.1.7 Javadoc Javadoc y el Programa Javadoc Recomendaciones para la Documentacin Sintaxis de Javadoc

    Lecturas:

    Requeridas: o Java Software, Sun Microsystems, Inc., How to Write Doc

    Comments for the Javadoc Tool (Cmo Escribir Comentarios Doc para la Herramienta Javadoc). Este documento describe las convenciones utilizadas para escribir comentarios Javadoc en Sun.

    Secuencia: Lee las secciones "Formato de un Comentario Doc," "Descripciones," "Una Gua de Estilo" y "Convenciones de Etiquetas".

    Javadoc y el Programa Javadoc

    Adems de los estilos de comentarios de una sola lnea y de mltiples lneas que existen en Java, est disponible un nuevo y funcional estilo. Se llama Javadoc. Los comentarios Javadoc son escritos por el programador y despus procesados por el programa Javadoc. El programa analiza los comentarios Javadoc y la estructura general del programa, produciendo un conjunto de pginas HTML que sirven como la documentacin del programa.

    Recomendaciones para la Documentacin

    Resulta mucho ms costoso el mantenimiento que el desarrollo del software. El trabajo de mantenimiento se simplifica en la medida en que el software est bien documentado. Muchos programadores documentan el programa despus de terminarlo. Esto es un error. La documentacin debe realizarse a la par de la codificacin. Dejarlo para despus representa una tarea muy difcil al final que traer casi siempre como consecuencia un programa mal documentado.

    El uso de Javadoc mejora la documentacin. La documentacin de todo el API de Java est en formato Javadoc. Tambin al emplear Javadoc se disminuye en gran medida la necesidad de utilizar comentarios convencionales en el cdigo fuente.

    Sintaxis de Javadoc

    Los comentarios en Javadoc inician con la secuencia "diagonal-asterisco-asterisco" (/**) y cierran con una secuencia "asterisco-diagonal" (*/), ya sea en una o ms lneas. Cuando

  • estos delimitadores se extienden a ms de una lnea, cada lnea interna comienza con un solo asterisco ( * ), sangrado de tal manera que est alineado con el primer asterisco que inici el comentario. La secuencia de cierre tambin debe alinearse con el primer asterisco de la secuencia de apertura. El texto del comentario comienza un espacio despus del asterisco que comienza la lnea. La estructura de varias lneas se muestra enseguida:

    /** * body text * body text * body text */

    La estructura de una sola lnea, se muestra a continuacin:

    /** body text */

    La mayora de los comentarios en Javadoc incluyen etiquetas Javadoc. Estas etiquetas comienzan con el smbolo "arroba" ( @ ), seguido del nombre de la etiqueta. Cada etiqueta describe un atributo particular de la entidad que se est comentando. Existen muchas etiquetas. A continuacin se presenta un subconjunto formado con las etiquetas ms comunes:

    Etiquetas de Javadoc Comunes

    1. @author nombre del programador; utilizado para clases 2. @version versin del programa; utilizado para clases 3. @param descripcin de un parmetro formal; utilizado para mtodos y constructores 4. @return descripcin de un valor de retorno; utilizado para mtodos 5. @exception (o @throws) descripcin de una excepcin; utilizado para mtodos y

    constructores 6. @see referencia a una entidad relacionada; utilizada para clases, constructores, mtodos

    y campos de datos

    Cuando se utilizan diferentes etiquetas en un comentario Javadoc, deben aparecer en el orden mencionado anteriormente.

    Los comentarios Javadoc pueden contener etiquetas HTML. Utiliza etiquetas HTML cuando sea apropiado.

    El siguiente ejemplo ilustra el uso de varias etiquetas:

    1: 2: 3: 4: 5: 6: 7:

    /** * Esta clase almacena el valor de dos enteros. * Esta clase es escrita con el propsito de hacer una demostracin de los * comentarios Javadoc. Los comentarios Javadoc para las clases, pueden ser * separados en dos partes: una parte de descripcin y una parte de etiquetas.

  • 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:

    * Esta es la parte de descripcin. Las partes deben estar separadas por una * lnea de comentario vaca. * Tambin, no debe lneas entre el final del comentario Javadoc * y el inicio de la entidad que describe. * * @author Lily Hou * @author Sean Bufano * @version 1.0.0 */ public class TwoInts { private int first; private int second; /** * Inicializa ambos enteros en 0. */ public TwoInts() { this.first = 0; this.second = 0; } /** * Inicializa ambos enteros con los argumentos. * * @param initialFirst valor al cual es inicializado el campo * first * @param initialSecond valor al cual es inicializado el campo * second */ public TwoInts(int initialFirst, int initialSecond) { this.first = initialFirst; this.second = initialSecond; } /** * Calcula la suma de dos enteros. * * @return regresa la suma de dos enteros */ public int sum() { return this.first + this.second; } /** * Incrementa el campo first por el argumento. * * @param value el valor por el cual se incrementar el campo * first */ public void addToFirst(int value) { this.first += value;

  • 57: 58: 59: 60: 61: 62: 63:

    } }

    Listado 1 TwoInts.java

    Una vez que los comentarios Javadoc estn completos, emplea el comando javadoc para generar la documentacin del programa. La siguiente figura ilustra la sintaxis del comando javadoc:

    Figura 1 Comando Javadoc

    Esto generar una coleccin de pginas HTML que sern la documentacin de la clase TwoInts. Esta coleccin puede visualizarse en un navegador Web. Abre el archivo index.html que se encuentra en el directorio que almacena el archivo fuente TwoInts.

    Este curso solamente requiere comentarios Javadoc para las entidades public y protected clases, constructores, mtodos y variables precedidas por las palabras clave public o protected.

  • 1.1.8 Depurando El Proceso de Depuracin Instrucciones de Imprimir El Depurador

    El Proceso de Depuracin

    Depuracin (debugging) es el proceso de identificar un error y corregirlo. Una depuracin efectiva no se realiza de manera natural. Para muchos desarrolladores, la depuracin consume muchas horas. El tiempo necesario para encontrar un error y corregirlo depender de tu competencia en depuracin. El uso de estrategias ad hoc, como tratar de adivinar por ejemplo, puede hacer que desperdicies grandes cantidades de tiempo sin obtener ningn resultado. El proceso de identificar un error debe ser metdico y no debe comenzar hasta que el desarrollador ha entendido bien el cdigo del programa. En esta pgina, describiremos una tcnica de depuracin y presentaremos algunas herramientas para depuracin. En la pgina Depurando con Eclipse, utilizaremos la tcnica descrita aqu para depurar un programa.

    La siguiente figura muestra un resumen de una efectiva tcnica para depurar un programa:

    Figura 1 Proceso de Depuracin

  • 1. Crea un caso de prueba: para diagnosticar y corregir un error, debes ser capaz de reproducirlo. Para ahorrar tiempo en las pruebas, crea un caso de prueba pequeo que reproduzca el error. Implementa este caso de prueba en una clase separada o en el mtodo main del programa que ser depurado.

    2. Ubica el cdigo que causa el error. Un buen lugar para comenzar la bsqueda es el caso de prueba mismo: encuentra la lnea de cdigo en el caso de prueba donde aparece el error. Esta lnea te dirigir al cdigo que contiene el error. Una vez que hayas ubicado el cdigo, estudia sus estructuras de control y sus variables. Determina cmo se espera que se comporte el cdigo y qu valores se espera que contengan las variables.

    3. Repasa el cdigo lnea por lnea. Presta particular atencin a las instrucciones que asignen un nuevo valor a una variable relevante. Identifica el cdigo que causa el error.

    4. No asumas que el error es causado por un problema de lgica en esta parte del cdigo. Puede ser causado por datos errneos originados en otras reas del cdigo. Si es as, localiza el cdigo donde se originaron los datos errneos y repite la operacin a partir del paso 2.

    5. Repara el cdigo: o La correccin no debe "esconder", "maquillar" o "reprimir" el error. o La correccin no debe introducir nuevos errores. El desarrollador debe

    entender cmo la correccin afecta otras partes del cdigo porque una correccin puede tener efectos colaterales inesperados.

    o Resulta prudente revisar el cdigo circundante. En muchos casos, hay ms de un error en la misma parte del cdigo.

    Instrucciones de Imprimir

    El uso de instrucciones de imprimir es una tcnica comn. Est disponible en muchos idiomas y es fcil de implementar. Las instrucciones de imprimir se utilizan para desplegar informacin importante mientras se ejecuta el cdigo. La informacin puede incluir:

    Los mtodos llamados El valor de los parmetros El valor del las variables de control de un bucle El valor de las variables locales El valor de las variables de instancia

    El siguiente ejemplo ilustra el uso de instrucciones de imprimir para rastrear la ejecucin de una aplicacin. En esta aplicacin, la clase SumCalculator solicita un rango al usuario y despus despliega la suma de los enteros que se encuentran en dicho rango. El mtodo sumRange contiene las instrucciones de imprimir que rastrean la ejecucin del cdigo del mtodo. La primera instruccin de imprimir despliega el nombre del mtodo y el valor de

  • sus argumentos. La segunda instruccin de imprimir despliega los valores de las variables locales.

    1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:

    import java.io.*; /** * Esta aplicacin despliega la suma de enteros en el rango * especificado. * * @author * @version 1.0.0 */ public class SumCalculator { private static BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); private static PrintWriter stdOut = new PrintWriter(System.out, true); private static PrintWriter stdErr = new PrintWriter(System.err, true); /** * Regresa la suma de enteros en el rango * especificado [inferior,superior]. * * @param lower el lmite inferior. * @param upper el lmite superior. * @return regresa la suma de enteros en el rango * especificado [inferior,superior]. */ public static int sumRange(int lower, int upper) { stdErr.println(" sumRange called. lower:" + lower + " upper:" + upper); int total = 0; for (int i = lower ; i

  • 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71:

    int upper; try { stdErr.print("lower limit: "); stdErr.flush(); lower = Integer.parseInt(stdIn.readLine()); stdErr.print("upper limit: "); stdErr.flush(); upper = Integer.parseInt(stdIn.readLine()); stdOut.println("The result is: " + sumRange(lower, upper)); } catch (NumberFormatException nfe) { stdErr.println(nfe); } catch (IOException ioe) { stdErr.println(ioe); } } }

    Listado 1 SumCalculator

    Cuando la aplicacin es ejecutada, despliega el nombre del mtodo, los argumentos del mtodo y los valores de la variable de control del bucle y de la variable local total en cada iteracin del bucle. Toma en cuenta que este cdigo no tiene ningn error. Slo estamos demostrando cmo pueden ser utilizadas las instrucciones de imprimir para rastrear la ejecucin de un programa.

    Figura 2 Ejecucin de SumNumbers

    El Depurador

    Un depurador (debugger) es una herramienta conveniente para localizar la fuente de los errores. Un depurador te permite ejecutar una lnea a la vez y observar su efecto en las variables del programa. Existen muchos depuradores de Java disponibles:

    Ambientes integrados de desarrollo (Integrated Development Environments o IDE), tales como Eclipse, Sun ONE Studio, Borland JBuilder y BlueJ, contienen sus propios depuradores.

  • Depuradores grficos autnomos, tales como JSwat y DDD

    Depuradores basados en texto, tales como Sun jdb

    Casi todos los depuradores tienen las siguientes capacidades:

    1. Establecer puntos de ruptura. Un punto de ruptura (breakpoint) es un marcador en el cdigo que indica que el depurador puede detener la ejecucin del programa antes de ejecutar una cierta instruccin.

    2. Recorrer un programa paso a paso. Una vez que un punto de ruptura detienen la ejecucin de un programa, el depurador provee el siguiente conjunto de comandos para continuar la ejecucin.

    o resume. Continuar con la ejecucin, no solamente paso a paso. o step into. Ejecutar la lnea actual. Si la lnea actual llama a un mtodo, el

    depurador "pasa adentro de" el mtodo, es decir, la ejecucin se mueve al mtodo llamado y se detiene antes de la primera lnea del mtodo llamado.

    o step over. Ejecuta la lnea actual. Si la lnea actual llama a un mtodo, el depurador "pasa sobre" el mtodo, es decir, el mtodo es ejecutado y la ejecucin se detiene antes de que la siguiente lnea del mtodo actual.

    o step return. Se ejecuta hasta que el mtodo actual es completado y regresa al mtodo que hace la llamada. La ejecucin se detiene antes de la siguiente lnea del mtodo que hace la llamada.

    3. Examinar los datos. El depurador puede desplegar los valores de las variables del mtodo y la clase actuales. Si una variable es un objeto compuesto que contiene mltiples elementos, el usuario puede "abrir" el objeto e inspeccionar el valor de cada elemento.

    4. Rastreo de la pila. Cuando un punto de ruptura es alcanzado y la ejecucin suspendida, el depurador puede desplegar la secuencia de los mtodos llamados. El usuario puede examinar los valores de las variables locales que se encuentran en los mtodos llamados.

    Como puedes ver, un depurador es una herramienta poderosa para monitorear la ejecucin de un programa e identificar la fuente de errores. Sin embargo, un depurador es solamente una herramienta. La habilidad para identificar y eliminar errores depende, en ltima instancia, de la competencia del programador.

  • 1.1.9 Depurando con Eclipse Introduccin El Ejemplo Crear el Proyecto Importar la Clase Employee Ejecutar la Aplicacin Mostrar los Nmeros de Lnea Depurar la Clase Colocar un Punto de Ruptura Monitorear la Ejecucin Diagnosticar y Corregir el Error

    Introduccin

    En esta seccin, realizaremos una demostracin del proceso de depuracin utilizando un depurador. Utilizaremos el depurador incluido en Eclipse. Las funciones bsicas provistas por este depurador son similares a las que ofrecen otros depuradores. Por lo tanto, tambin puedes avanzar en este tutorial utilizando otro depurador.

    El Ejemplo

    La clase Employee representa a un empleado en un sistema de nminas. Los objetos de la clase Employee contienen el nombre y el salario del empleado. El salario de un empleado es una funcin del salario por hora, el nmero de horas trabajadas y las comisiones de ventas. La informacin de cada empleado es almacenada en una cadena con el siguiente formato:

    name_hourlyWage_hoursWorked_sale1,sale2,...,salen

    Donde,

    name es el nombre del empleado wagePerHour es el salario por hora del empleado hoursWorked es el nmero de horas que el empleado trabaj sale1,sale2,...,salen son las ventas del empleado

    El sueldo ganado por un empleado se calcula utilizando la siguiente ecuacin.

    earning = hourlyWage * hoursWorked + (sale1 + sale2 + ... + salen) * 0.02

    Donde, el valor 0.02 corresponde al 2% por comisin de ventas.

    A continuacin se presenta el cdigo de la clase Employee:

    1: import java.io.*;

  • 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58:

    import java.util.*; /** * Modela la informacin de un empleado. * * @author * @version 1.0.0 */ public class Employee { private static PrintWriter stdErr = new PrintWriter(System.err, true); private final static double SALE_COMMISSION = 0.02; private final static String DATA_DELIM = "_"; private final static String SALES_DELIM = ","; private String name; private double earnings; /** * Caso de prueba para la clase Employee * * @param args no utilizado. */ public static void main(String[] args) { String data = "John Smith_10.00_20_1000.0,100.0,0.0"; Employee employee = new Employee(data); try { if (employee.getEarnings() == 222.0) { stdErr.println("Test 1 passed"); } else { stdErr.println("Test 1 failed"); } } catch (NumberFormatException iae) { stdErr.println("Test 1 failed, " + iae); } data = "John Smith_10.00_20_1000.0,100.0"; employee = new Employee(data); try { if (employee.getEarnings() == 222.0) { stdErr.println("Test 2 passed"); } else { stdErr.println("Test 2 failed"); } } catch (NumberFormatException iae) { stdErr.println("Test 2 failed, " + iae); }

  • 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115:

    } /** * Construye un objeto Employee con la * informacin especificada en el parmetro data. * * Los datos de entrada tienen el siguiente formato: * * * nombre_salarioHora_horasTrabajadas_venta1,venta2,...,ventan * * * Los campos de venta almacenan la cantidad de cada venta realizada por el * empleado. * * * @param data una cadena con la informacin del empleado. * @throws NumberFormatException si los datos contienen nmeros * invlidos */ public Employee(String data) throws NumberFormatException { StringTokenizer tokenizer = new StringTokenizer(data, DATA_DELIM); try { this.name = tokenizer.nextToken(); double hourlyWage = Double.parseDouble(tokenizer.nextToken()); int hoursWorked = Integer.parseInt(tokenizer.nextToken()); double commission = (tokenizer.hasMoreTokens()) ? computeCommission(tokenizer.nextToken()) : 0; this.earnings = hourlyWage * hoursWorked + commission; } catch (NumberFormatException nfe) { throw new NumberFormatException( "bad employee data: " + data); } } /** * Obtiene el nombre del empleado. * * @return regresa una cadena con el nombre del empleado. */ public String getName() { return this.name; } /**

  • 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156:

    * Obtiene los ingresos del empleado. * * @return los ingresos del empleado. */ public double getEarnings() { return this.earnings; } /* * Calcula la comisin del empleado con los datos * especificados en el parmetro. * * @param data una cadena con los datos de las ventas del empleado. * @return regresa la comisin ganada por el empleado. * @throws NumberFormatException si los datos contienen nmeros * invlidos */ private double computeCommission(String data) throws NumberFormatException { StringTokenizer tokenizer = new StringTokenizer(data, SALES_DELIM); double total = 0.0; try { String token = tokenizer.nextToken(); while (tokenizer.hasMoreTokens()) { token = tokenizer.nextToken(); total += Double.parseDouble(token); } } catch (NumberFormatException nfe) { throw new NumberFormatException( "bad sales data: " + data); } return total * SALE_COMMISSION; } }

    Listado 1 Employee.java

    En la lnea 92, el operador condicional ( ? : ) utiliza el valor booleano de una expresin para decidir cul de dos otras expresiones debe ser evaluada. La siguiente asignacin:

    variable = condicin ? expresin1 : expresin2;

    es equivalente al siguiente cdigo:

    if (condicin) {

  • variable = expresin1; } else { variable = expresin2; }

    El constructor utiliza un objeto StringTokenizer para extraer cada parte de la informacin del empleado. Entonces, asigna valores a las variables name y earning. El mtodo computeCommission regresa la comisin del empleado a partir de la informacin de ventas. Esta implementacin de la clase Employee es incorrecta. En el resto de esta pgina, utilizaremos el depurador Eclipse para encontrar el error y corregirlo.

    Crear el Proyecto

    El primer paso es crear el proyecto de Java.

    1. Abre Eclipse y despus abre la perspectiva de Java. 2. En el men File (archivo), apunta a New (nuevo) y despus selecciona Project

    (proyecto). 3. En el asistente de New Project, selecciona Java en el panel izquierdo, da un clic en

    Java Project (proyecto de Java) en el panel derecho y despus elige Next (siguiente).

    Figura 1 Ventana de nuevo proyecto

    4. En el cuadro de Project name (nombre de proyecto) escribe Employee. Selecciona el recuadro de Use default (utilizar predeterminado) y presiona Finish (terminar).

  • Figura 2 Asistente del proyecto de Java

    5. Eclipse aade el nuevo proyecto a la lista que se encuentra en la vista Projects (proyectos).

  • Figura 3 Proyecto Employee

    Impo