Monografias.com
Recomendar este trabajo a un amigo
Principal Buscar Registrarse Gratis Bajar Trabajo

 

1. INTRODUCCI�N A JAVA

 

 1.1 Origen de Java

Sun Microsystems, l�der en servidores para Internet, uno de cuyos lemas desde hace mucho tiempo es "the network is the computer" (lo que quiere dar a entender que el verdadero ordenador es la red en su conjunto y no cada m�quina individual), es quien ha desarrollado el lenguaje Java, en un intento de resolver simult�neamente todos los problemas que se le plantean a los desarrolladores de software por la proliferaci�n de arquitecturas incompatibles, tanto entre las diferentes m�quinas como entre los diversos sistemas operativos y sistemas de ventanas que funcionaban sobre una misma m�quina, a�adiendo la dificultad de crear aplicaciones distribuidas en una red como Internet.

 

He podido leer m�s de cinco versiones distintas sobre el origen, concepci�n y desarrollo de Java, desde la que dice que este fue un proyecto que rebot� durante mucho tiempo por distintos departamentos de Sun sin que nadie le prestara ninguna atenci�n, hasta que finalmente encontr� su nicho de mercado en la aldea global que es Internet; hasta la m�s difundida, que justifica a Java como lenguaje de peque�os electrodom�sticos.

 

Hace algunos a�os, Sun Microsystems decidi� intentar introducirse en el mercado de la electr�nica de consumo y desarrollar programas para peque�os dispositivos electr�nicos. Tras unos comienzos dudosos, Sun decidi� crear una filial, denominada FirstPerson Inc., para dar margen de maniobra al equipo responsable del proyecto.

 

El mercado inicialmente previsto para los programas de FirstPerson eran los equipos dom�sticos: microondas, tostadoras y, fundamentalmente, televisi�n interactiva. Este mercado, dada la falta de pericia de los usuarios para el manejo de estos dispositivos, requer�a unos interfaces mucho m�s c�modos e intuitivos que los sistemas de ventanas que proliferaban en el momento.

 

Otros requisitos importantes a tener en cuenta eran la fiabilidad del c�digo y la facilidad de desarrollo. James Gosling, el miembro del equipo con m�s experiencia en lenguajes de programaci�n, decidi� que las ventajas aportadas por la eficiencia de C++ no compensaban el gran coste de pruebas y depuraci�n. Gosling hab�a estado trabajando en su tiempo libre en un lenguaje de programaci�n que �l hab�a llamado Oak, el cual, a�n partiendo de la sintaxis de C++, intentaba remediar las deficiencias que iba observando.

 

Los lenguajes al uso, como C o C++, deben ser compilados para un chip, y si se cambia el chip, todo el software debe compilarse de nuevo. Esto encarece mucho los desarrollos y el problema es especialmente acusado en el campo de la electr�nica de consumo. La aparici�n de un chip m�s barato y, generalmente, m�s eficiente, conduce inmediatamente a los fabricantes a incluirlo en las nuevas series de sus cadenas de producci�n, por peque�a que sea la diferencia en precio ya que,

multiplicada por la tirada masiva de los aparatos, supone un ahorro considerable. Por tanto, Gosling decidi� mejorar las caracter�sticas de Oak y utilizarlo.

 

El primer proyecto en que se aplic� este lenguaje recibi� el nombre de proyecto Green y consist�a en un sistema de control completo de los aparatos electr�nicos y el entorno de un hogar. Para ello se construy� un ordenador experimental denominado *7 (Star Seven). El sistema presentaba una interfaz basada en la representaci�n de la casa de forma animada y el control se llevaba a cabo mediante una pantalla sensible al tacto. En el sistema aparec�a Duke, la actual mascota de Java.

 

Posteriormente se aplic� a otro proyecto denominado VOD (Video On Demand) en el que se empleaba como interfaz para la televisi�n interactiva. Ninguno de estos proyectos se convirti� nunca en un sistema comercial, pero fueron desarrollados enteramente en un Java primitivo y fueron como su bautismo de fuego.

 

Una vez que en Sun se dieron cuenta de que a corto plazo la televisi�n interactiva no iba a ser un gran �xito, urgieron a FirstPerson a desarrollar con rapidez nuevas estrategias que produjeran beneficios. No lo consiguieron y FirstPerson cerr� en la primavera de 1994.

 

Pese a lo que parec�a ya un olvido definitivo, Bill Joy, cofundador de Sun y uno de los desarrolladores principales del Unix de Berkeley, juzg� que Internet podr�a llegar a ser el campo de juego adecuado para disputar a Microsoft su primac�a casi absoluta en el terreno del software, y vio en Oak el instrumento id�neo para llevar a cabo estos planes. Tras un cambio de nombre y modificaciones de dise�o, el lenguaje Java fue presentado en sociedad en agosto de 1995.

 

Lo mejor ser� hacer caso omiso de las historias que pretenden dar carta de naturaleza a la clarividencia industrial de sus protagonistas; porque la cuesti�n es si independientemente de su origen y entorno comercial, Java ofrece soluciones a nuestras expectativas. Porque tampoco vamos a desechar la penicilina aunque haya sido su origen fruto de la casualidad.

 

 

1.2 Caracter�sticas de Java

Las caracter�sticas principales que nos ofrece Java respecto a cualquier otro lenguaje de programaci�n, son:

 

Simple

Java ofrece toda la funcionalidad de un lenguaje potente, pero sin las caracter�sticas menos usadas y m�s confusas de �stos. C++ es un lenguaje que adolece de falta de seguridad, pero C y C++ son lenguajes m�s difundidos, por ello Java se dise�� para ser parecido a C++ y as� facilitar un r�pido y f�cil aprendizaje.

Java elimina muchas de las caracter�sticas de otros lenguajes como C++, para mantener reducidas las especificaciones del lenguaje y a�adir caracter�sticas muy �tiles como el garbage collector (reciclador de memoria din�mica). No es necesario preocuparse de liberar memoria, el reciclador se encarga de ello y como es un thread de baja prioridad, cuando entra en acci�n, permite liberar bloques de memoria muy grandes, lo que reduce la fragmentaci�n de la memoria.

 

Java reduce en un 50% los errores m�s comunes de programaci�n con lenguajes como C y C++ al eliminar muchas de las caracter�sticas de �stos, entre las que destacan:

aritm�tica de punteros

no existen referencias

registros (struct)

definici�n de tipos (typedef)

macros (#define)

necesidad de liberar memoria (free)

 

Aunque, en realidad, lo que hace es eliminar las palabras reservadas (struct, typedef), ya que las clases son algo parecido.

 

Adem�s, el int�rprete completo de Java que hay en este momento es muy peque�o, solamente ocupa 215 Kb de RAM.

 

Orientado a objetos

Java implementa la tecnolog�a b�sica de C++ con algunas mejoras y elimina algunas cosas para mantener el objetivo de la simplicidad del lenguaje. Java trabaja con sus datos como objetos y con interfaces a esos objetos. Soporta las tres caracter�sticas propias del paradigma de la orientaci�n a objetos: encapsulaci�n, herencia y polimorfismo. Las plantillas de objetos son llamadas, como en C++, clases y sus copias, instancias. Estas instancias, como en C++, necesitan ser construidas y destruidas en espacios de memoria.

 

Java incorpora funcionalidades inexistentes en C++ como por ejemplo, la resoluci�n din�mica de m�todos. Esta caracter�stica deriva del lenguaje Objective C, propietario del sistema operativo Next. En C++ se suele trabajar con librer�as din�micas (DLLs) que obligan a recompilar la aplicaci�n cuando se retocan las funciones que se encuentran en su interior. Este inconveniente es resuelto por Java mediante una interfaz espec�fica llamada RTTI (RunTime Type Identification) que define la interacci�n entre objetos excluyendo variables de instancias o implementaci�n de m�todos. Las clases en Java tienen una representaci�n en el runtime que permite a los programadores interrogar por el tipo de clase y enlazar din�micamente la clase con el resultado de la b�squeda.

 

Distribuido

Java se ha construido con extensas capacidades de interconexi�n TCP/IP. Existen librer�as de rutinas para acceder e interactuar con protocolos como http y ftp. Esto permite a los programadores acceder a la informaci�n a trav�s de la red con tanta facilidad como a los ficheros locales.

 

La verdad es que Java en s� no es distribuido, sino que proporciona las librer�as y herramientas para que los programas puedan ser distribuidos, es decir, que se corran en varias m�quinas, interactuando.

 

Robusto

Java realiza verificaciones en busca de problemas tanto en tiempo de compilaci�n como en tiempo de ejecuci�n. La comprobaci�n de tipos en Java ayuda a detectar errores, lo antes posible, en el ciclo de desarrollo. Java obliga a la declaraci�n expl�cita de m�todos, reduciendo as� las posibilidades de error. Maneja la memoria para eliminar las preocupaciones por parte del programador de la liberaci�n o corrupci�n de memoria.

 

Tambi�n implementa los arrays aut�nticos, en vez de listas enlazadas de punteros, con comprobaci�n de l�mites, para evitar la posibilidad de sobreescribir o corromper memoria resultado de punteros que se�alan a zonas equivocadas. Estas caracter�sticas reducen dr�sticamente el tiempo de desarrollo de aplicaciones en Java.

 

Adem�s, para asegurar el funcionamiento de la aplicaci�n, realiza una verificaci�n de los byte-codes, que son el resultado de la compilaci�n de un programa Java. Es un c�digo de m�quina virtual que es interpretado por el int�rprete Java. No es el c�digo m�quina directamente entendible por el hardware, pero ya ha pasado todas las fases del compilador: an�lisis de instrucciones, orden de operadores, etc., y ya tiene generada la pila de ejecuci�n de �rdenes.

 

Java proporciona, pues:

 

Comprobaci�n de punteros

Comprobaci�n de l�mites de arrays

Excepciones

Verificaci�n de byte-codes

Arquitectura neutral

Para establecer Java como parte integral de la red, el compilador Java compila su c�digo a un fichero objeto de formato independiente de la arquitectura de la m�quina en que se ejecutar�. Cualquier m�quina que tenga el sistema de ejecuci�n (run-time) puede ejecutar ese c�digo objeto, sin importar en modo alguno la m�quina en que ha sido generado. Actualmente existen sistemas run-time para Solaris 2.x, SunOs 4.1.x, Windows 95, Windows NT, Linux, Irix, Aix, Mac, Apple y probablemente haya grupos de desarrollo trabajando en el porting a otras plataformas.

 

  

 

 

 

El c�digo fuente Java se "compila" a un c�digo de bytes de alto nivel independiente de la m�quina. Este c�digo (byte-codes) est� dise�ado para ejecutarse en una m�quina hipot�tica que es implementada por un sistema run-time, que s� es dependiente de la m�quina.

En una representaci�n en que tuvi�semos que indicar todos los elementos que forman parte de la arquitectura de Java sobre una plataforma gen�rica, obtendr�amos una figura como la siguiente:

 

 

 

En ella podemos ver que lo verdaderamente dependiente del sistema es la M�quina Virtual Java (JVM) y las librer�as fundamentales, que tambi�n nos permitir�an acceder directamente al hardware de la m�quina. Adem�s, habr� APIs de Java que tambi�n entren en contacto directo con el hardware y ser�n dependientes de la m�quina, como ejemplo de este tipo de APIs podemos citar:

 

Java 2D: gr�ficos 2D y manipulaci�n de im�genes

Java Media Framework : Elementos cr�ticos en el tiempo: audio, video...

Java Animation: Animaci�n de objetos en 2D

Java Telephony: Integraci�n con telefon�a

Java Share: Interacci�n entre aplicaciones multiusuario

Java 3D: Gr�ficos 3D y su manipulaci�n

 

Seguro

La seguridad en Java tiene dos facetas. En el lenguaje, caracter�sticas como los punteros o el casting impl�cito que hacen los compiladores de C y C++ se eliminan para prevenir el acceso ilegal a la memoria. Cuando se usa Java para crear un navegador, se combinan las caracter�sticas del lenguaje con protecciones de sentido com�n aplicadas al propio navegador.

 

El lenguaje C, por ejemplo, tiene lagunas de seguridad importantes, como son los errores de alineaci�n. Los programadores de C utilizan punteros en conjunci�n con operaciones aritm�ticas. Esto le permite al programador que un puntero referencie a un lugar conocido de la memoria y pueda sumar (o restar) alg�n valor, para referirse a otro lugar de la memoria. Si otros programadores conocen nuestras estructuras de datos pueden extraer informaci�n confidencial de nuestro sistema. Con un lenguaje como C, se pueden tomar n�meros enteros aleatorios y convertirlos en punteros para luego acceder a la memoria:

 

printf( "Escribe un valor entero: " );

scanf( "%u",&puntero );

printf( "Cadena de memoria: %s\n",puntero );

 

Otra laguna de seguridad u otro tipo de ataque, es el Caballo de Troya. Se presenta un programa como una utilidad, resultando tener una funcionalidad destructiva. Por ejemplo, en UNIX se visualiza el contenido de un directorio con el comando ls. Si un programador deja un comando destructivo bajo esta referencia, se puede correr el riesgo de ejecutar c�digo malicioso, aunque el comando siga haciendo la funcionalidad que se le supone, despu�s de lanzar su carga destructiva.

Por ejemplo, despu�s de que el caballo de Troya haya enviado por correo el /etc/shadow a su creador, ejecuta la funcionalidad de ls persentando el contenido del directorio. Se notar� un retardo, pero nada inusual.

 

El c�digo Java pasa muchos tests antes de ejecutarse en una m�quina. El c�digo se pasa a trav�s de un verificador de byte-codes que comprueba el formato de los fragmentos de c�digo y aplica un probador de teoremas para detectar fragmentos de c�digo ilegal -c�digo que falsea punteros, viola derechos de acceso sobre objetos o intenta cambiar el tipo o clase de un objeto-.

 

Si los byte-codes pasan la verificaci�n sin generar ning�n mensaje de error, entonces sabemos que:

 

 

El Cargador de Clases tambi�n ayuda a Java a mantener su seguridad, separando el espacio de nombres del sistema de ficheros local, del de los recursos procedentes de la red. Esto limita cualquier aplicaci�n del tipo Caballo de Troya, ya que las clases se buscan primero entre las locales y luego entre las procedentes del exterior.

 

Las clases importadas de la red se almacenan en un espacio de nombres privado, asociado con el origen. Cuando una clase del espacio de nombres privado accede a otra clase, primero se busca en las clases predefinidas (del sistema local) y luego en el espacio de nombres de la clase que hace la referencia. Esto imposibilita que una clase suplante a una predefinida.

En resumen, las aplicaciones de Java resultan extremadamente seguras, ya que no acceden a zonas delicadas de memoria o de sistema, con lo cual evitan la interacci�n de ciertos virus. Java no posee una sem�ntica espec�fica para modificar la pila de programa, la memoria libre o utilizar objetos y m�todos de un programa sin los privilegios del kernel del sistema operativo. Adem�s, para evitar modificaciones por parte de los crackers de la red, implementa un m�todo ultraseguro de autentificaci�n por clave p�blica. El Cargador de Clases puede verificar una firma digital antes de realizar una instancia de un objeto. Por tanto, ning�n objeto se crea y almacena en memoria, sin que se validen los privilegios de acceso. Es decir, la seguridad se integra en el momento de compilaci�n, con el nivel de detalle y de privilegio que sea necesario.

 

Dada, pues la concepci�n del lenguaje y si todos los elementos se mantienen dentro del est�ndar marcado por Sun, no hay peligro. Java imposibilita, tambi�n, abrir ning�n fichero de la m�quina local (siempre que se realizan operaciones con archivos, �stas trabajan sobre el disco duro de la m�quina de donde parti� el applet), no permite ejecutar ninguna aplicaci�n nativa de una plataforma e impide

que se utilicen otros ordenadores como puente, es decir, nadie puede utilizar nuestra m�quina para hacer peticiones o realizar operaciones con otra. Adem�s, los int�rpretes que incorporan los navegadores de la Web son a�n m�s restrictivos. Bajo estas condiciones (y dentro de la filosof�a de que el �nico ordenador seguro es el que est� apagado, desenchufado, dentro de una c�mara acorazada en un bunker y rodeado por mil soldados de los cuerpos especiales del ej�rcito), se puede considerar que Java es un lenguaje seguro y que los applets est�n libres de virus.

 

Respecto a la seguridad del c�digo fuente, no ya del lenguaje, JDK proporciona un desemsamblador de byte-code, que permite que cualquier programa pueda ser convertido a c�digo fuente, lo que para el programador significa una vulnerabilidad total a su c�digo. Utilizando javap no se obtiene el c�digo fuente original, pero s� desmonta el programa mostrando el algoritmo que se utiliza, que es lo realmente interesante. La protecci�n de los programadores ante esto es utilizar llamadas a programas nativos, externos (incluso en C o C++) de forma que no sea descompilable todo el c�digo; aunque as� se pierda portabilidad. Esta es otra de las cuestiones que Java tiene pendientes.

 

Portable

M�s all� de la portabilidad b�sica por ser de arquitectura independiente, Java implementa otros est�ndares de portabilidad para facilitar el desarrollo. Los enteros son siempre enteros y adem�s, enteros de 32 bits en complemento a 2. Adem�s, Java construye sus interfaces de usuario a trav�s de un sistema abstracto de ventanas de forma que las ventanas puedan ser implantadas en entornos Unix, Pc o Mac.

 

Interpretado

El int�rprete Java (sistema run-time) puede ejecutar directamente el c�digo objeto. Enlazar (linkar) un programa, normalmente, consume menos recursos que compilarlo, por lo que los desarrolladores con Java pasar�n m�s tiempo desarrollando y menos esperando por el ordenador. No obstante, el compilador actual del JDK es bastante lento. Por ahora, que todav�a no hay compiladores espec�ficos de Java para las diversas plataformas, Java es m�s lento que otros lenguajes de programaci�n, como C++, ya que debe ser interpretado y no ejecutado como sucede en cualquier programa tradicional.

 

Se dice que Java es de 10 a 30 veces m�s lento que C, y que tampoco existen en Java proyectos de gran envergadura como en otros lenguajes. La verdad es que ya hay comparaciones ventajosas entre Java y el resto de los lenguajes de programaci�n, y una ingente cantidad de folletos electr�nicos que supuran fanatismo en favor y en contra de los distintos lenguajes contendientes con Java. Lo que se suele dejar de lado en todo esto, es que primero habr�a que decidir hasta que punto Java, un lenguaje en pleno desarrollo y todav�a sin definici�n definitiva, est� maduro como lenguaje de programaci�n para ser comparado con otros; como por ejemplo con Smalltalk, que lleva m�s de 20 a�os en cancha.

 

La verdad es que Java para conseguir ser un lenguaje independiente del sistema operativo y del procesador que incorpore la m�quina utilizada, es tanto interpretado como compilado. Y esto no es ning�n contrasentido, me explico, el c�digo fuente escrito con cualquier editor se compila generando el byte-code. Este c�digo intermedio es de muy bajo nivel, pero sin alcanzar las instrucciones m�quina propias de cada plataforma y no tiene nada que ver con el p-code de Visual Basic. El byte-code corresponde al 80% de las instrucciones de la aplicaci�n. Ese mismo c�digo es el que se puede ejecutar sobre cualquier plataforma. Para ello hace falta el run-time, que s� es completamente dependiente de la m�quina y del sistema operativo, que interpreta din�micamente el byte-code y a�ade el 20% de instrucciones que faltaban para su ejecuci�n. Con este sistema es f�cil crear aplicaciones multiplataforma, pero para ejecutarlas es necesario que exista el run-time correspondiente al sistema operativo utilizado.

 

 

 

Multithreaded

Al ser multithreaded (multihilvanado, en mala traducci�n), Java permite muchas actividades simult�neas en un programa. Los threads (a veces llamados, procesos ligeros), son b�sicamente peque�os procesos o piezas independientes de un gran proceso. Al estar los threads contruidos en el lenguaje, son m�s f�ciles de usar y m�s robustos que sus hom�logos en C o C++.

 

El beneficio de ser miltithreaded consiste en un mejor rendimiento interactivo y mejor comportamiento en tiempo real. Aunque el comportamiento en tiempo real est� limitado a las capacidades del sistema operativo subyacente (Unix, Windows, etc.), a�n supera a los entornos de flujo �nico de programa (single-threaded) tanto en facilidad de desarrollo como en rendimiento.

 

Cualquiera que haya utilizado la tecnolog�a de navegaci�n concurrente, sabe lo frustrante que puede ser esperar por una gran imagen que se est� trayendo. En Java, las im�genes se pueden ir trayendo en un thread independiente, permitiendo que el usuario pueda acceder a la informaci�n en la p�gina sin tener que esperar por el navegador.

 

Dinamico

Java se beneficia todo lo posible de la tecnolog�a orientada a objetos. Java no intenta conectar todos los m�dulos que comprenden una aplicaci�n hasta el tiempo de ejecuci�n. Las librer�a nuevas o actualizadas no paralizar�n las aplicaciones actuales (siempre que mantengan el API anterior).

 

Java tambi�n simplifica el uso de protocolos nuevos o actualizados. Si su sistema ejecuta una aplicaci�n Java sobre la red y encuentra una pieza de la aplicaci�n que no sabe manejar, tal como se ha explicado en p�rrafos anteriores, Java es capaz de traer autom�ticamente cualquiera de esas piezas que el sistema necesita para funcionar.

Java, para evitar que los m�dulos de byte-codes o los objetos o nuevas clases, haya que estar tray�ndolos de la red cada vez que se necesiten, implementa las opciones de persistencia, para que no se eliminen cuando de limpie la cach� de la m�quina.

 

�Cu�l es la ventaja de todo esto?�Qu� gano con Java?

 

 

 

 

Todo esto suena muy bonito pero tambien se tienen algunas limitantes:

 

 

Pero en general Java posee muchas ventajas y se pueden hacer cosas muy interesantes con esto. Hay que prestar especial atenci�n a lo que est� sucediendo en el mundo de la computaci�n, a pesar de que Java es relativamente nuevo, posee mucha fuerza y es tema de moda en cualquier medio computacional. Muchas personas apuestan a futuro y piensan en Java. La pregunta es : �Estar�n en lo correcto? La verdad es que no se, pero este manual no es para filosofar sobre el futuro del lenguaje sino para aprender a programarlo.

 

 

1.3 HotJava

HotJava, en pocas palabras, es un navegador con soporte Java (Java-enabled), desarrollado en Java. Como cualquier navegador de Web, HotJava puede decodificar HTML est�ndar y URLs est�ndares, aunque no soporta completamente el est�ndar HTML 3.0. La ventaja sobre el resto de navegadores, sin soporte Java, es que puede ejecutar programas Java sobre la red. La diferencia con Netscape, es que tiene implementado completamente los sistemas de seguridad que propone Java, esto significa que puede escribir y leer en el disco local, aunque esto hace disminuir la seguridad, ya que se pueden grabar en nuestro disco programas que contengan c�digo malicioso e introducirnos un virus, por ejemplo. No obstante, el utilizar esta caracter�stica de HotJava es decisi�n del usuario.

 

 

1.4 Java para aplicaciones corporativas

Java actualmente est� en boca de todos, Java e Intranet son las palabras de moda. Pero, surge la pregunta de si esta es una buena tecnolog�a para desarrollar aplicaciones corporativas. Y la respuesta es afirmativa y voy a proponer argumentos para esa afirmaci�n. En donde la red sea algo cr�tico, Java facilita tremendamente la vida de la programaci�n corporativa.

 

Durante a�os, las grandes empresas se han convencido de que la "red" corporativa es la arteria por donde fluye la sangre que mantiene vivo su negocio. Desde el gran servidor de sus oficinas centrales, hasta los servidores de las delegaciones, las estaciones de trabajo de los programadores y la marabunta de PCs, la informaci�n va fluyendo de unos a otros. Para muchas compa��as, la Red es la Empresa.

Si esta red no se mantiene sana, los pedidos no llegan, el inventario no se actualiza, el software no se desarrolla adecuadamente, los clientes no est�n satisfechos y, fundamentalmente, el dinero no entra. La necesidad de diagnosticar y reducir la arterioesclerosis de la red, hace que se est�n inyectando continuamente nuevas metodolog�as que subsanen este grave problema.

 

 

�Es Java la medicina? Est� claro que cuando vemos un cepillo animado limpiando los dientes, cubos movi�ndose en 3-D, o una banda de gatos locos en applets de Java, nos convencemos de que es el lenguaje id�neo para Internet. Pero, qu� pasa con las aplicaciones corporativas, �ser�a una buena tecnolog�a all� donde la red es el punto cr�tico? Vamos a intentar responder comparando las capacidades de Java contra la lista de necesidades de la red corporativa.

 

Desarrollo r�pido de aplicaciones

Hace a�os, se dec�a que los programadores pronto desaparecer�an. Los generadores autom�ticos de programas, eliminar�an a los generadores humanos y el mundo ser�a un lugar mejor para vivir. Desafortunadamente, quienes dec�an esto no tuvieron en cuenta una acelerada demanda de software de calidad para muy diferentes aplicaciones. Sin embargo, la tecnolog�a de objetos pronto vino a intentar facilitar la tarea, adoptando el modelo de "generar parte de un programa", as�, generando la parte b�sica de un programa (los objetos), se podr�a conectar con otras partes para proporcionar diferentes utilidades al usuario.

 

El lenguaje C++ es una buena herramienta, pero no cumple totalmente la premisa. Visual Basic y NextStep, se acercan cada vez m�s al poder de los objetos. Java facilita la creaci�n de entornos de desarrollo-aplicaciones de modo similar, pero adem�s es flexible, poderoso y efectivo. Los programadores ahora disponen de herramientas de programaci�n de calidad beta, que apuntan hacia esa meta, como son el Java WorkShop de SunSoft, el entorno Java de Borland, el Caf� de Symantec, y pronto, herramientas m�s sofisticadas como Netcode o FutureTense. Esto proporciona una gran progresi�n a los entornos de desarrollo Java.

 

Aplicaciones efectivas y eficientes

Las aplicaciones que se crean en grandes empresas deben ser m�s efectivas que eficientes; es decir, conseguir que el programa funcione y el trabajo salga adelante es m�s importante que el que lo haga eficientemente. Esto no es una cr�tica, es una realidad de la programaci�n corporativa. Al ser un lenguaje m�s simple que cualquiera de los que ahora est�n en el caj�n de los programadores, Java permite a �stos concentrarse en la mec�nica de la aplicaci�n, en vez de pasarse horas y horas incorporando APIs para el control de las ventanas, controlando minuciosamente la memoria, sincronizando los ficheros de cabecera y corrigiendo los ag�nicos mensajes del linker. Java tiene su propio toolkit para interfaces, maneja por s� mismo la memoria que utilice la aplicaci�n, no permite ficheros de cabecera separados (en aplicaciones puramente Java) y solamente usa enlace din�mico.

Muchas de las implementaciones de Java actuales son puros int�rpretes. Los byte-codes son interpretados por el sistema run-time de Java, la M�quina Virtual Java (JVM), sobre el ordenador del usuario. Aunque ya hay ciertos proveedores que ofrecen compiladores nativos Just-In-Time (JIT). Si la M�quina Virtual Java dispone de un compilador instalado, las secciones (clases) del byte-code de la aplicaci�n se compilar�n hacia la arquitectura nativa del ordenador del usuario.

 

Los programas Java en ese momento rivalizar�n con el rendimiento de programas en C++. Los compiladores JIT no se utilizan en la forma tradicional de un compilador; los programadores no compilan y distribuyen binarios Java a los usuarios. La compilaci�n JIT tiene lugar a partir del byte-code Java, en el sistema del usuario, como una parte (opcional) del entorno run-time local de Java.

 

Muchas veces, los programadores corporativos, ansiosos por exprimir al m�ximo la eficiencia de su aplicaci�n, empiezan a hacerlo demasiado pronto en el ciclo de vida de la aplicaci�n. Java permite algunas t�cnicas innovadoras de optimizaci�n. Por ejemplo, Java es inherentemente multithreaded, a la vez que ofrece posibilidades de multithread como la clase Thread y mecanismos muy sencillos de usar de sincronizaci�n; Java en s� utiliza threads. Los desarrolladores de compiladores inteligentes pueden utilizar esta caracter�stica de Java para lanzar un thread que compruebe la forma en que se est� utilizando la aplicaci�n. M�s espec�ficamente, este thread podr�a detectar qu� m�todos de una clase se est�n usando con m�s frecuencia e invocar a sucesivos niveles de optimizaci�n en tiempo de ejecuci�n de la aplicaci�n. Cuanto m�s tiempo est� corriendo la aplicaci�n o el applet, los m�todos estar�n cada vez m�s optimizados (Guava de Softway es de este tipo).

 

Si un compilador JIT est� embebido en el entorno run-time de Java, el programador no se preocupa de hacer que la aplicaci�n se ejecute �ptimamente. Siempre he pensado que en los Sistemas Operativos tendr�a que aplicarse esta filosof�a; un optimizador progresivo es un paso m�s hacia esta idea.

Portabilidad para programador y programa

En una empresa de relativo tama�o hay una pl�yade diferente de ordenadores. Probablemente nos encontremos con estaciones de trabajo Sun para el desarrollo de software, hordas de PCs para cada empleado, alg�n Mac en el departamento de documentaci�n, una estaci�n de trabajo HP en administraci�n y una estaci�n SGI en la sala de demos. Desarrollar aplicaciones corporativas para un grupo tan diferente de plataformas en excesivamente complejo y caro. Hasta ahora era complicado convencer a los programadores de cada arquitectura que utilizasen un API com�n para reducir el coste de las aplicaciones.

 

Con un entorno run-time de Java portado a cada una de las arquitecturas de las plataformas presentes en la empresa y una buena librer�a de clases ("packages" en Java), los programadores pueden entenderse y encontrar muy interesante trabajar con Java. Esta posibilidad har� tender a los programadores hacia Java, justo donde otros intentos anteriores con entornos universales (como Galaxy o XVT) han fracasado. Estos APIs eran simplemente inadecuados, no orientados a redes y, verdaderamente, pesados.

 

Una vez que los programas est�n escritos en Java, otro lado interesante del asunto es que los programadores tambi�n son portables. El grupo de programadores de la empresa puede ahora enfrentarse a un desarrollo para cualquiera de las plataformas. La parte del cliente y del servidor de una aplicaci�n estar�n ahora escritas en el mismo lenguaje. Ya no ser� necesario tener un grupo que desarrolle en Solaris en del departamento de I+D, programadores trabajando sobre Visual Basic en el departamento de documentaci�n y programadores sobre GNU en proyectos especiales; ahora todos ellos podr�n estar juntos y formar el grupo de software de la empresa.

 

Costes de desarrollo

En contraste con el alto coste de los desarrollos realizados sobre estaciones de trabajo, el coste de creaci�n de una aplicaci�n Java es similar al de desarrollar sobre un PC.

 

Desarrollar utilizando un software caro para una estaci�n de trabajo (ahora barata) es un problema en muchas empresas. La eficiencia del hardware y el poco coste de mantenimiento de una estaci�n de trabajo Sun, por ejemplo, resulta muy atractivo para las empresas; pero el coste adicional del entorno de desarrollo con C++ es prohibitivo para la gran mayor�a de ellas. La llegada de Java e Intranet reducen considerablemente estos costes. Las herramientas Java ya no est�n en el entorno de precios de millones de pesetas, sino a los niveles confortables de precio de las herramientas de PCs. Y con el crecimiento cada d�a mayor de la comunidad de desarrolladores de software freeware y shareware que incluso proporcionan el c�digo fuente, los programadores corporativos tienen un amplio campo donde moverse y muchas oportunidades de aprender y muchos recursos a su disposici�n.

 

El �xito que Internet ha proporcionado a los equipos de software corporativos es un regalo. El precio del software es ahora el mismo para un poderoso equipo corriendo Unix que para un PC. Incluso Netscape tiene al mismo precio la versi�n Unix de su servidor Web SuiteSpot que la versi�n PC/NT. Esta es la filosof�a de precios que parece ser ser� la que se siga con las herramientas basadas en Java.

 

Mantenimiento y soporte

Un problema bien conocido que ocurre con el software corporativo es la demanda de cuidados y realimentaci�n. Java no es, ciertamente, la cura para la enfermedad del mantenimiento, pero tiene varias caracter�sticas que har�n la vida del enfermero m�s f�cil.

 

Uno de los componentes del JDK es javadoc. Si se usan ciertas convenciones en el c�digo fuente Java (como comenzar un comentario con /** y terminarlo con */), javadoc se puede f�cilmente generar p�ginas HTML con el contenido de esos comentarios, que pueden visualizarse en cualquier navegador. La documentaci�n del API de Java ha sido creada de este modo. Esto hace que el trabajo de documentar el c�digo de nuevas clases Java sea trivial.

 

Otro gran problema del desarrollador corporativo es la creaci�n y control de makefiles. Leerse un makefile es como estar leyendo la historia de empresa. Normalmente se pasan de programador a programador, quitando la informaci�n que no es esencial, siempre que se puede. Esto hace que muchos de los makefiles de las aplicaciones contengan docenas de librer�as, una mir�ada de ficheros de cabecera y ultra-confusos macros. Es como mirar en el est�mago de la ballena de Jon�s.

 

Java reduce las dependencia de complejos makefiles dr�sticamente. Primero, no hay ficheros de cabecera. Java necesita que todo el c�digo fuente de una clase se encuentre en un solo fichero. Java tiene la inteligencia de make en el propio lenguaje para simplificar la compilaci�n de byte-codes.

Por ejemplo:

 

public class pepe { // Fichero: pepe.java

Guitarra flamenca ;

}

public class guitarra { // Fichero: guitarra.java

}

 

% javac -verbose pepe.java

[parsed pepe.java in 720ms]

[loaded C:\JAVA\BIN\..\classes\java\lang\Object.class in 220ms]

[checking class pepe]

[parsed .\\Guitarra.java in 50ms]

[wrote pepe.class]

[checking class Guitarra]

[wrote .\\Guitarra.class]

[done in 2300ms]

El compilador Java se da cuenta de que necesita compilar el fichero guitarra.java. Ahora vamos a forzarlo a que recompile pepe.java sin cambiar guitarra.java, podremos comprobar que el compilador de byte-code Java no recompila innecesariamente el fichero guitarra.java.

 

% javac -verbose pepe.java

[parsed pepe.java in 440ms]

[loaded C:\JAVA\BIN\..\classes\java\lang\Object.class in 160ms]

[checking class pepe]

[loaded .\\Guitarra.java in 0ms]

[wrote pepe.class]

[done in 1860ms]

 

Ahora, si modificamos guitarra.java (a�adiendo, por ejemplo, otro miembro a la clase) y compilamos pepe.java, el compilador Java se dar� cuenta de que debe recompilar tanto pepe.java como guitarra.java

 

% javac -verbose pepe.java

[parsed pepe.java in 710ms]

[loaded C:\JAVA\BIN\..\classes\java\lang\Object.class in 220ms]

[checking class pepe]

[parsed .\\Guitarra.java in 0ms]

[wrote pepe.class]

[checking class Guitarra]

[wrote .\\Guitarra.class]

[done in 2640ms]

 

En el libro Just Java de Peter van der Linden hay un cap�tulo excelente acerca del compilador de Java, si tienes oportunidad, no dejes de leerlo.

 

Aprendizaje

Si la empresa est� llena de programadores de C++ con alguna experiencia en el manejo de librer�a gr�ficas, aprender�n r�pidamente lo esencial de Java. Si el equipo de ingenieros no conoce C++, pero maneja cualquier otro lenguaje de programaci�n orientada a objetos, les llevar� pocas semanas dominar la base de Java. Lo que s� que no es cierto es que haya que aprender C++ antes de aprender Java.

 

Si los ingenieros de la empresa no conocen ning�n lenguaje orientado a objetos, s� que tienen que aprender los fundamentos de esta tecnolog�a antes de nada, y luego aplicarlos a la programaci�n con Java. El an�lisis y dise�o orientado a objetos debe ser comprendido antes de intentar nada con Java. Los programadores de Java sin un fondo de conocimientos de OOA/D producir�n c�digo pobre. Adem�s, los libros sobre Java crecen como la espuma, ya hay m�s de 25 publicados, y si buscas "Progamming in Java" en la Red, encontrar�s 312 Web sites, y 30 m�s dedicados a "Learning Java". Y si esto, evidentemente, no es el sustituto de un instructor humano, hay ya varias empresas que ofrecen ense�anza de Java, entre ellas, Sun.

 

 

 

2. INSTALACI�N DEL JDK

 

 

Actualmente ya hay entornos de desarrollo integrados completos para Java, diferentes del JDK de Sun. Symantec dispone de un compilador de Java para Windows 95 y Windows NT, con las ventajas del aumento de velocidad de proceso y capacidades multimedia que esto proporciona, Symantec Caf�. Borland tambi�n est� trabajando en ello y la nueva versi�n de su entorno de desarrollo soporta Java. Sun ha lanzado la versi�n comercial de su propio entorno de desarrollo para Java, el Java Workshop, enteramente escrito en Java. Y Microsoft ha puesto en el mercado Visual J++, que sigue el estilo de todas sus herramientas de desarrollo.

 

No obstante, trataremos solamente el JDK, que hasta el momento es lo m�s conocido. El entorno b�sico del JDK de Java que proporciona Sun est� formado por herramientas en modo texto, que son: java, int�rprete que ejecuta programas en byte-code. javac, compilador de Java que convierte el c�digo fuente en byte-code. javah, crea ficheros de cabecera para implementar m�todos para cualquier clase. javap, es un descompilador de byte-code a c�digo fuente Java. javadoc, es un generador autom�tico de documentos HTML a partir del c�digo fuente Java. javaprof, es un profiler para aplicaciones de un solo thread. HotJava, es un navegador Web escrito completamente en Java.

 

El entorno habitual pues, consiste en un navegador que pueda ejecutar applets, un compilador que convierta el c�digo fuente Java a byte-code y el int�rprete Java para ejecutar los programas. Estos son los componenetes b�sicos para desarrollar algo en Java. No obstante se necesita un editor para escribir el c�digo fuente, y no son estrictamente necesarias otras herramientas como el debugger, un entorno visual, la documentaci�n o un visualizador de jerarqu�a de clases. Tan es as�, que disponiendo del navegador Netscape 2.0 no se necesita ni tan siquiera el JDK (a petici�n de varios amigos que disfrutan del uso de Linux pero no disponen de soporte ELF para poder utilizar el JDK portado por Randy Chapman, les indicar� como conseguir utilizar el compilador embebido en Netscape).

 

2.1 Windows

La versi�n del JDK para Windows es un archivo autoextraible. Se necesitan alrededor de 6 Mb de espacio libre en disco. Ejecutar el fichero, que desempaquetar� el contenido del archivo. El directorio donde se instale no es importante, pero supondremos que se instala en el raiz del disco C:, en cuyo caso los archivos colgar�n de c:\java. Es necesario a�adir c:\java\bin a la variable de entorno PATH.

 

Adem�s de los ficheros java, el JDK incluye dos librer�as din�micas, MSVCRT20.DLL y MFC30.DLL, que se instalar�n en el directorio de Java. Si tienes ninguna copia de estos ficheros en tu ordenador (probablemente en el directorio system de Windows) copia estos ficheros en el directorio c:\java\bin. Si estos ficheros ya est�n en tu ordenador, elimina las copias extra que instala el JDK.

 

 

2.2 Solaris

La versi�n del JDK para Solaris es un fichero tar comprimido. Se necesitan alrededor de 9 Mb de disco para descomprimir el JDK, aunque el doble de espacio ser�a una cifra m�s c�moda. Ejecutar los siguientes comandos:

 

% uncompress JDK-beta-solaris2-sparc.tar.Z

% tar xvf JDK-beta-solaris2-sparc-tar

 

Puedes descomprimir el archivo en tu directorio home, o, si tienes privilegios de supervisor, en alg�n sitio m�s conveniente de /usr/local para que todos los usuarios tengan acceso a los ficheros. Sin embargo, los privilegios del supervisor no son necesarios para instalar y ejecutar Java. Por simplicidad, supondr� que has descomprimido el JDK en /usr/local, aunque el path completo donde se haga no tiene relevancia (tambi�n es posible colocarlo en /opt que es donde residen todas las aplicaciones de Solaris). Si lo has colocado en un sitio diferente, simplemente sustituye /usr/local por ese directorio (si lo has descomprimido en tu home, puedes utilizar ~/java y ~/hotjava, en vez del path completo).

 

Es necesario a�adir /usr/local/java/bin a la variable de entorno PATH. Utiliza el siguiente comando (suponiendo que tengas el shell csh o tcsh):

 

set path=($PATH /usr/local/java/bin)

 

Tambi�n puedes a�adir esta l�nea al final del fichero .profile y .cshrc, y ya tienes el sistema listo para ejecutar applets. Si quieres desembarazarte de la ventana que aparece cada vez que lances el appletviewer con la licencia de Sun, crea un directorio que se llame .hotjava en el directorio java/bin y ya no volver�s a verla.

 

 

2.3 Linux

Necesitas un kernel que soporte binarios ELF, por lo tanto tu Linux debe ser la versi�n 1.2.13 o superior, las anteriores tienen un bug que hacen que javac no funcione. Necesitas tambi�n Netscape, versi�n 2.0b4 o posterior. Sobre la versi�n 1.2.13 del kernel de Linux, hay que seguir los pasos que indico para conseguir que JDK funcione:

 

linux.jdk-1.0 try1.common.tar.gz a

/usr/local, descomprimirlo y hacer 'tar xvf'

 

J_HOME=/usr/local/java

PRG=/usr/local/java/bin

 

 

 

 

 

 

Esto deber�a ser suficiente para compilar cualquier cosa en Java/Linux. En caso de tener problemas, es el momento de recurrir a las FAQ.

 

Siguiendo los pasos indicados ya se puede ejecutar el ejemplo del Tic-Tac-Toe que propone la hoja de instalaci�n que Sun ha incluido en todas sus versiones y que en Linux consistir�a en cambiarse al directorio de la demo:

 

% cd /usr/local/java/demo/TicTacToe

 

ejecutar el visualizador de applets sobre la p�gina html:

 

% appletviewer example1.html

 

y a jugar a las tres en raya. Por cierto, que el algoritmo que usa el ordenador est� falseado por lo que es posible ganarle.

 

 

2.4 Compilaci�n sin JDK

Parece raro, pero se puede conseguir. Lo �nico necesario es el navegador Netscape 2.0. Este navegador, junto con la m�quina virtual Java (JVM) y el sistema run-time, tiene un compilador Java.

Si no se dispone del Java Development Kit (JDK), que no est� disponible para todas las plataformas, pero s� de la versi�n de Netscape para nuestra plataforma, aqu� van los pasos a seguir para utilizar el compilador de Java embebido en Netscape.

 

Como necesito partir de alg�n punto para tomarlo como referencia, voy a suponer que estamos sobre Linux y que vamos a prescindir del JDK de Randy Chapman. Lo que habr�a que hacer ser�a lo siguiente.

 

 

 

setenv CLASSPATH

.:/usr/local/netscape/java/classes/moz2_0.zip :

/usr/local/netscape/java/classes/classes.zip

 

 

netscape -java [clase]

(sustituir el nombre de la clase de la aplicaci�n -la que contiene la rutina main-

en vez de [clase]).

 

 

netscape -java sun.applet.AppletViewer [clase]

 

Desgraciadamente, la sentencia anterior no parece funcionar en todos los

sistemas. Hay amigos m�os que no han sido capaces de visualizar applets con

este m�todo.

 

Para aprovechar el tiempo, se puede crear un script que recoja los pasos 3, 4 y 6. Si estamos utilizando el csh, el contenido del script ser�a:

 

#/bin/csh -f setenv CLASSPATH

.:/usr/local/netscape/java/classes/moz2_0.zip:

/usr/local/netscape/java/classes/classes.zip

netscape -java sun.tools.javac.Main $1

y lo almacenar�amos como javac. Se ha de hacer el script ejecutable y cambiar /bin/csh por el path completo donde est� situado el csh. De forma semejante podemos definir el int�rprete java y el appletviewer, sustituyendo la l�nea adecuada de llamada a Netscape.

 

 

 

3. CONCEPTOS B�SICOS DE JAVA

 

 

3.1 Programaci�n en Java

Cuando se programa en Java, se coloca todo el c�digo en m�todos, de la misma forma que se escriben funciones en lenguajes como C.

 

Comentarios

En Java hay tres tipos de comentarios:

 

// comentarios para una sola l�nea

 

/* comentarios de una o

m�s l�neas

*/

 

/** comentario de documentaci�n, de una o m�s l�neas

*/

 

Los dos primeros tipos de comentarios son los que todo programador conoce y se utilizan del mismo modo. Los comentarios de documentaci�n, colocados inmediatamente antes de una declaraci�n (de variable o funci�n), indican que ese comentario ha de ser colocado en la documentaci�n que se genera autom�ticamente cuando se utiliza la herramienta de Java, javadoc. Dichos comentarios sirven como descripci�n del elemento declarado permitiendo generar una documentaci�n de nuestras clases escrita al mismo tiempo que se genera el c�digo.

 

En este tipo de comentario para documentaci�n, se permite la introducci�n de algunos tokens o palabras clave, que har�n que la informaci�n que les sigue aparezca de forma diferente al resto en la documentaci�n.

 

Identificadores

Los identificadores nombran variables, funciones, clases y objetos; cualquier cosa que el programador necesite identificar o usar.

 

En Java, un identificador comienza con una letra, un subrayado (_) o un s�mbolo de d�lar ($). Los siguientes caracteres pueden ser letras o d�gitos. Se distinguen las may�sculas de las min�sculas y no hay longitud m�xima.

 

Ser�an identificadores v�lidos:

identificador

nombre_usuario

Nombre_Usuario

_variable_del_sistema

$transaccion

y su uso ser�a, por ejemplo:

int contador_principal;

char _lista_de_ficheros;

float $cantidad_en_Ptas;

 

Palabras clave

Las siguientes son las palabras clave que est�n definidas en Java y que no se pueden utilizar como indentificadores:

 

abstract continue for new switch

boolean default goto null synchronized

break do if package this

byte double implements private threadsafe

byvalue else import protected throw

case extends instanceof public transient

catch false int return true

char final interface short try

class finally long static void

const float native super while

 

 

Palabras Reservadas

Adem�s, el lenguaje se reserva unas cuantas palabras m�s, pero que hasta ahora no tienen un cometido espec�fico. Son:

 

cast future generic inner

operator outer rest var

 

 

Literales

Un valor constante en Java se crea utilizando una representaci�n literal de �l. Java utiliza cinco tipos de elementos: enteros, reales en coma flotante, booleanos, caracteres y cadenas, que se pueden poner en cualquier lugar del c�digo fuente de Java. Cada uno de estos literales tiene un tipo correspondiente asociado con �l.

 

Enteros:

byte 8 bits complemento a dos

short 16 bits complemento a dos

int 32 bits complemento a dos

long 64 bits complemento a dos

Por ejemplo: 21 077 0xDC00

 

Reales en coma flotante:

float 32 bits IEEE 754

double 64 bits IEEE 754

Por ejemplo: 3.14 2e12 3.1E12

 

Booleanos:

true

false

 

Caracteres:

Por ejemplo: a \t \u???? [????] es un n�mero unicode

Cadenas:

Por ejemplo: "Esto es una cadena literal"

 

Arrays

Se pueden declarar en Java arrays de cualquier tipo:

 

char s[];

int iArray[];

 

Incluso se pueden construir arrays de arrays:

 

int tabla[][] = new int[4][5];

 

Los l�mites de los arrays se comprueban en tiempo de ejecuci�n para evitar desbordamientos y la corrupci�n de memoria.

 

En Java un array es realmente un objeto, porque tiene redefinido el operador []. Tiene una funci�n miembro: length. Se puede utilizar este m�todo para conocer la longitud de cualquier array.

 

int a[][] = new int[10][3];

a.length; /* 10 */

a[0].length; /* 3 */

 

Para crear un array en Java hay dos m�todos b�sicos. Crear un array vac�o:

 

int lista[] = new int[50];

 

o se puede crear ya el array con sus valores iniciales:

 

String nombres[] = {

"Juan","Pepe","Pedro","Maria"

};

 

Esto que es equivalente a:

 

String nombres[];

nombres = new String[4];

nombres[0] = new String( "Juan" );

nombres[1] = new String( "Pepe" );

nombres[2] = new String( "Pedro" );

nombres[3] = new String( "Maria" );

 

No se pueden crear arrays est�ticos en tiempo de compilaci�n:

int lista[50]; // generar� un error en tiempo de compilaci�n

Tampoco se puede rellenar un array sin declarar el tama�o con el operador new:

 

int lista[];

for( int i=0; i < 9; i++ )

lista[i] = i;

 

Es decir, todos los arrays en Java son est�ticos. Para convertir un array en el equivalente a un array din�mico en C/C++, se usa la clase vector, que permite operaciones de inserci�n, borrado, etc. en el array.

 

Operadores

Los operadores de Java son muy parecidos en estilo y funcionamiento a los de C. En la siguiente tabla aparecen los operadores que se utilizan en Java, por orden de precedencia:

 

. [] ()

++ --

! ~ instanceof

* / %

+ -

<< >> >>>

< > <= >= == !=

& ^ |

&& ||

? :

= op= (*= /= %= += -= etc.) ,

 

Los operadores num�ricos se comportan como esperamos:

 

int + int = int

 

Los operadores relacionales devuelven un valor booleano.

 

Para las cadenas, se pueden utilizar los operadores relacionales para comparaciones adem�s de + y += para la concatenaci�n:

String nombre = "nombre" + "Apellido";

 

El operador = siempre hace copias de objetos, marcando los antiguos para borrarlos, y ya se encargar� el garbage collector de devolver al sistema la memoria ocupada por el objeto eliminado.

 

Separadores

S�lo hay un par de secuencias con otros caracteres que pueden aparecer en el c�digo Java; son los separadores simples, que van a definir la forma y funci�n del c�digo. Los separadores admitidos en Java son:

 

() - par�ntesis. Para contener listas de par�metros en la definici�n y llamada a m�todos. Tambi�n se utiliza para definir precedencia en expresiones, contener expresiones para control de flujo y rodear las conversiones de tipo.

 

{} - llaves. Para contener los valores de matrices inicializadas autom�ticamente. Tambi�n se utiliza para definir un bloque de c�digo, para clases, m�todos y �mbitos locales.

 

[ ] - corchetes. Para declarar tipos matriz. Tambi�n se utiliza cuando se referencian valores de matriz.

 

; - punto y coma. Separa sentencias.

 

, - coma. Separa identificadores consecutivos en una declaraci�n de variables. Tambi�n se utiliza para encadenar sentencias dentro de una sentencia for.

 

. - punto. Para separar nombres de paquete de subpaquetes y clases. Tambi�n se utiliza para separar una variable o m�todo de una variable de referencia.

 

 

3.2 Control de Flujo

Muchas de las sentencias de control del flujo del programa se han tomado del C:

 

Sentencias de Salto

 

if/else

if( Boolean ) {

sentencias;

}

else {

sentencias;

}

 

switch

 

switch( expr1 ) {

case expr2:

sentencias;

break;

case expr3:

sentencias;

break;

default:

sentencias;

break;

}

 

 

Sentencias de Bucle

Bucles for

 

for( expr1 inicio; expr2 test; expr3 incremento ) {

sentencias;

}

 

El siguiente trocito de c�digo Java que dibuja varias l�neas en pantalla alternando sus colores entre rojo, azul y verde. Este fragmento ser�a parte de una funci�n Java (m�todo):

 

int contador;

for( contador=1; contador <= 12; contador++ ) {

switch( contador % 3 ) {

case 0:

setColor( Color.red );

break;

case 1:

setColor( Color.blue );

break;

case 2:

setColor( Color.green );

break;

}

g.drawLine( 10,contador*10,80,contador*10 );

}

 

Tambi�n se soporta el operador coma (,) en los bucles for

 

for( a=0,b=0; a < 7; a++,b+=2 )

 

Bucles while

 

while( Boolean ) {

sentencias;

}

 

Bucles do/while

 

do {

sentencias;

}while( Boolean );

 

 

Excepciones

try-catch-throw

 

try {

sentencias;

} catch( Exception ) {

sentencias;

}

 

Java implementa excepciones para facilitar la construcci�n de c�digo robusto. Cuando ocurre un error en un programa, el c�digo que encuentra el error lanza una excepci�n, que se puede capturar y recuperarse de ella. Java proporciona muchas excepciones predefinidas.

 

Control General del Flujo

break [etiqueta]

continue [etiqueta]

return expr;

etiqueta: sentencia;

 

En caso de que nos encontremos con bucles anidados, se permite el uso de etiquetas para poder salirse de ellos, por ejemplo:

 

uno: for( )

{

dos: for( )

{

continue; // seguir�a en el bucle interno

continue uno; // seguir�a en el bucle principal

break uno; // se saldr�a del bucle principal

}

}

 

En el c�digo de una funci�n siempre hay que ser consecuentes con la declaraci�n que se haya hecho de ella. Por ejemplo, si se declara una funci�n para que devuelva un entero, es imprescindible que se coloque un return final para salir de esa funci�n, independientemente de que haya otros en medio del c�digo que tambi�n provoquen la salida de la funci�n. En caso de no hacerlo se generar� un Warning, y el c�digo Java no se puede compilar con Warnings.

 

int func()

{

if( a == 0 )

return 1;

return 0; // es imprescindible porque se retorna un entero

}

 

 

3.3 Clases

Las clases son lo m�s simple de Java. Todo en Java forma parte de una clase, es una clase o describe como funciona una clase. El conocimiento de las clases es fundamental para poder entender los programas Java.

 

Todas las acciones de los programas Java se colocan dentro del bloque de una clase o un objeto. Todos los m�todos se definen dentro del bloque de la clase, Java no soporta funciones o variables globales. Esto puede despistar a los programadores de C++, que pueden definir m�todos fuera del bloque de la clase, pero esta posibilidad es m�s un intento de no separarse mucho y ser compatible con C, que un buen dise�o orientado a objetos. As� pues, el esqueleto de cualquier aplicaci�n Java se basa en la definici�n de una clase.

 

Todos los datos b�sicos, como los enteros, se deben declarar en las clases antes de hacer uso de ellos. En C la unidad fundamental son los ficheros con c�digo fuente, en Java son las clases. De hecho son pocas las sentencias que se pueden colocar fuera del bloque de una clase. La palabra clave import (equivalente al #include) puede colocarse al principio de un fichero, fuera del bloque de la clase. Sin embargo, el compilador reemplazar� esa sentencia con el contenido del fichero que se indique, que consistir�, como es de suponer, en m�s clases.

 

Tipos de Clases

Hasta ahora s�lo se ha utilizado la palabra clave public para calificar el nombre de las clases que hemos visto, pero hay tres modificadores m�s. Los tipos de clases que podemos definir son:

abstract

Una clase abstract tiene al menos un m�todo abstracto. Una clase abstracta no se instancia, sino que se utiliza como clase base para la herencia.

 

final

Una clase final se declara como la clase que termina una cadena de herencia. No se puede heredar de una clase final. Por ejemplo, la clase Math es una clase final.

 

public

Las clases public son accesibles desde otras clases, bien sea directamente o por herencia. Son accesibles dentro del mismo paquete en el que se han declarado. Para acceder desde otros paquetes, primero tienen que ser importadas.

 

synchronizable

Este modificador especifica que todos los m�todos definidos en la clase son sincronizados, es decir, que no se puede acceder al mismo tiempo a ellos desde distintos threads; el sistema se encarga de colocar los flags necesarios para evitarlo. Este mecanismo hace que desde threads diferentes se puedan modificar las mismas variables sin que haya problemas de que se sobreescriban.

 

 

3.4 Variables y M�todos de Instancia

Una clase en Java puede contener variables y m�todos. Las variables pueden ser tipos primitivos como int, char, etc. Los m�todos son funciones.

 

Por ejemplo, en el siguiente trozo de c�digo podemos observarlo:

 

public MiClase {

int i;

public MiClase() {

i = 10;

}

public void Suma_a_i( int j ) {

i = i + j;

}

}

 

La clase MiClase contiene una variable (i) y dos m�todos, MiClase que es el constructor de la clase y Suma_a_i( int j ).

 

Ambito de una variable

Los bloques de sentencias compuestas en Java se delimitan con dos llaves. Las variables de Java s�lo son v�lidas desde el punto donde est�n declaradas hasta el final de la sentencia compuesta que la engloba. Se pueden anidar estas sentencias compuestas, y cada una puede contener su propio conjunto de declaraciones de variables locales. Sin embargo, no se puede declarar una variable con el mismo nombre que una de �mbito exterior.

 

El siguiente ejemplo intenta declarar dos variables separadas con el mismo nombre. En C y C++ son distintas, porque est�n declaradas dentro de �mbitos diferentes. En Java, esto es ilegal.

 

Class Ambito {

int i = 1; // �mbito exterior

{ // crea un nuevo �mbito

int i = 2; // error de compilaci�n

}

}

 

M�todos y Constructores

Los m�todos son funciones que pueden ser llamadas dentro de la clase o por otras clases. El constructor es un tipo espec�fico de m�todo que siempre tiene el mismo nombre que la clase.

 

Cuando se declara una clase en Java, se pueden declarar uno o m�s constructores opcionales que realizan la inicializaci�n cuando se instancia (se crea una ocurrencia) un objeto de dicha clase.

Utilizando el c�digo de ejemplo anterior, cuando se crea una nueva instancia de MiClase, se crean (instancian) todos los m�todos y variables, y se llama al constructor de la clase:

 

MiClase mc;

mc = new MiClase();

 

La palabra clave new se usa para crear una instancia de la clase. Antes de ser instanciada con new no consume memoria, simplemente es una declaraci�n de tipo. Despu�s de ser instanciado un nuevo objeto mc, el valor de i en el objeto mc ser� igual a 10. Se puede referenciar la variable (de instancia) i con el nombre del objeto:

 

mc.i++; // incrementa la instancia de i de mc

 

Al tener mc todas las variables y m�todos de MiClase, se puede usar la primera sintaxis para llamar al m�todo Suma_a_i() utilizando el nuevo nombre de clase mc:

 

mc.Suma_a_i( 10 );

 

y ahora la variable mc.i vale 21.

 

 

Finalizadores

Java no utiliza destructores (al contrario que C++) ya que tiene una forma de recoger autom�ticamente todos los objetos que se salen del alcance. No obstante proporciona un m�todo que, cuando se especifique en el c�digo de la clase, el reciclador de memoria (garbage collector) llamar�:

 

// Cierra el canal cuando este objeto es reciclado

protected void finalize() {

close();

}

 

3.5 Alcance de Objetos y Reciclado de Memoria

Los objetos tienen un tiempo de vida y consumen recursos durante el mismo. Cuando un objeto no se va a utilizar m�s, deber�a liberar el espacio que ocupaba en la memoria de forma que las aplicaciones no la agoten (especialmente las grandes).

En Java, la recolecci�n y liberaci�n de memoria es responsabilidad de un thread llamado automatic garbage collector (recolector autom�tico de basura). Este thread monitoriza el alcance de los objetos y marca los objetos que se han salido de alcance. Veamos un ejemplo:

String s; // no se ha asignado todavia

s = new String( "abc" ); // memoria asignada

s = "def"; // se ha asignado nueva memoria

// (nuevo objeto)

M�s adelante veremos en detalle la clase String, pero una breve descripci�n de lo que hace esto es; crear un objeto String y rellenarlo con los caracteres "abc" y crear otro (nuevo) String y colocarle los caracteres "def".

 

En esencia se crean dos objetos:

 

Objeto String "abc"

Objeto String "def"

 

Al final de la tercera sentencia, el primer objeto creado de nombre s que contiene "abc" se ha salido de alcance. No hay forma de acceder a �l. Ahora se tiene un nuevo objeto llamado s y contiene "def". Es marcado y eliminado en la siguiente iteraci�n del thread reciclador de memoria.

 

 

3.6 Herencia

La Herencia es el mecanismo por el que se crean nuevos objetos definidos en t�rminos de objetos ya existentes. Por ejemplo, si se tiene la clase Ave, se puede crear la subclase Pato, que es una especializaci�n de Ave.

class Pato extends Ave {

int numero_de_patas;

}

 

La palabra clave extends se usa para generar una subclase (especializaci�n) de un objeto. Una Pato es una subclase de Ave. Cualquier cosa que contenga la definici�n de Ave ser� copiada a la clase Pato, adem�s, en Pato se pueden definir sus propios m�todos y variables de instancia. Se dice que Pato deriva o hereda de Ave.

 

Adem�s, se pueden sustituir los m�todos proporcionados por la clase base. Utilizando nuestro anterior ejemplo de MiClase, aqu� hay un ejemplo de una clase derivada sustituyendo a la funci�n Suma_a_i():

 

import MiClase;

public class MiNuevaClase extends MiClase {

public void Suma_a_i( int j ) {

i = i + ( j/2 );

}

}

 

Ahora cuando se crea una instancia de MiNuevaClase, el valor de i tambi�n se inicializa a 10, pero la llamada al m�todo Suma_a_i() produce un resultado diferente:

 

MiNuevaClase mnc;

mnc = new MiNuevaClase();

mnc.Suma_a_i( 10 );

 

En Java no se puede hacer herencia m�ltiple. Por ejemplo, de la clase aparato con motor y de la clase animal no se puede derivar nada, ser�a como obtener el objeto toro mec�nico a partir de una m�quina motorizada (aparato con motor) y un toro (aminal). En realidad, lo que se pretende es copiar los m�todos, es decir, pasar la funcionalidad del toro de verdad al toro mec�nico, con lo cual no ser�a necesaria la herencia m�ltiple sino simplemente la compartici�n de funcionalidad que se encuentra implementada en Java a trav�s de interfaces.

 

 

3.7 Control de Acceso

Cuando se crea una nueva clase en Java, se puede especificar el nivel de acceso que se quiere para las variables de instancia y los m�todos definidos en la clase:

 

public

public void CualquieraPuedeAcceder(){}

 

Cualquier clase desde cualquier lugar puede acceder a las variables y m�todos de instacia p�blicos.

 

protected

protected void SoloSubClases(){}

 

S�lo las subclases de la clase y nadie m�s puede acceder a las variables y m�todos de instancia protegidos.

 

private

private String NumeroDelCarnetDeIdentidad;

 

Las variables y m�todos de instancia privados s�lo pueden ser accedidos desde dentro de la clase. No son accesibles desde las subclases.

friendly (sin declaraci�n espec�fica)

 

void MetodoDeMiPaquete(){}

 

Por defecto, si no se especifica el control de acceso, las variables y m�todos de instancia se declaran friendly (amigas), lo que significa que son accesibles por todos los objetos dentro del mismo paquete, pero no por los externos al paquete. Es lo mismo que protected.

 

Los m�todos protegidos (protected) pueden ser vistos por las clases derivadas, como en C++, y tambi�n, en Java, por los paquetes (packages). Todas las clases de un paquete pueden ver los m�todos protegidos de ese paquete. Para evitarlo, se deben declarar como private protected, lo que hace que ya funcione como en C++ en donde s�lo se puede acceder a las variables y m�todos protegidos de las clases derivadas.

 

 

3.8 Variables y M�todos Est�ticos

En un momento determinado se puede querer crear una clase en la que el valor de una variable de instancia sea el mismo (y de hecho sea la misma variable) para todos los objetos instanciados a partir de esa clase. Es decir, que exista una �nica copia de la variable de instancia. Se usar� para ello la palabra clave static.

 

class Documento extends Pagina {

static int version = 10;

}

 

El valor de la variable version ser� el mismo para cualquier objeto instanciado de la clase Documento. Siempre que un objeto instanciado de Documento cambie la variable version, �sta cambiar� para todos los objetos.

De la misma forma se puede declarar un m�todo como est�tico, lo que evita que el m�todo pueda acceder a las variables de instancia no est�ticas:

 

class Documento extends Pagina {

static int version = 10;

int numero_de_capitulos;

static void annade_un_capitulo() {

numero_de_capitulos++; // esto no funciona

}

static void modifica_version( int i ) {

version++; // esto si funciona

}

}

 

La modificaci�n de la variable numero_de_capitulos no funciona porque se est� violando una de las reglas de acceso al intentar acceder desde un m�todo est�tico a una variable no est�tica.

 

Todas las clases que se derivan, cuando se declaran est�ticas, comparten la misma p�gina de variables; es decir, todos los objetos que se generen comparten la misma zona de memoria. Las funciones est�ticas se usan para acceder solamente a variables est�ticas.

 

class UnaClase {

int var;

UnaClase()

{

var = 5;

}

UnaFuncion()

{

var += 5;

}

}

 

En el c�digo anterior, si se llama a la funci�n UnaFuncion a trav�s de un puntero a funci�n, no se podr�a acceder a var, porque al utilizar un puntero a funci�n no se pasa impl�citamente el puntero al propio objeto (this). Sin embargo, s� se podr�a acceder a var si fuese est�tica, porque siempre estar�a en la misma posici�n de memoria para todos los objetos que se creasen de UnaClase.

 

 

3.9 this Y super

Al acceder a variables de instancia de una clase, la palabra clave this hace referencia a los miembros de la propia clase. Volviendo al ejemplo de MiClase, se puede a�adir otro constructor de la forma siguiente:

 

public class MiClase {

int i;

public MiClase() {

i = 10;

}

// Este constructor establece el valor de i

public MiClase( int valor ) {

this.i = valor; // i = valor

}

public void Suma_a_i( int j ) {

i = i + j;

}

}

 

Aqu� this.i se refiere al entero i en la clase MiClase.

 

Si se necesita llamar al m�todo padre dentro de una clase que ha reemplazado ese m�todo, se puede hacer referencia al m�todo padre con la palabra clave super:

 

import MiClase;

public class MiNuevaClase extends MiClase {

public void Suma_a_i( int j ) {

i = i + ( j/2 );

super.Suma_a_i( j );

}

}

 

En el siguiente c�digo, el constructor establecer� el valor de i a 10, despu�s lo cambiar� a 15 y finalmente el m�todo Suma_a_i() de la clase padre (MiClase) lo dejar� en 25:

 

MiNuevaClase mnc;

mnc = new MiNuevaClase();

mnc.Suma_a_i( 10 );

 

 

3.10 Clases Abstractas

Una de las caracter�sticas m�s �tiles de cualquier lenguaje orientado a objetos es la posibilidad de declarar clases que definen como se utiliza solamente, sin tener que implementar m�todos. Esto es muy �til cuando la implementaci�n es espec�fica para cada usuario, pero todos los usuarios tienen que utilizar los mismos m�todos. Un ejemplo de clase abstracta en Java es la clase Graphics:

 

public abstract class Graphics {

public abstract void drawLine( int x1,int y1,int x2,

int y2 );

public abstract void drawOval( int x,int y,int width,

int height );

public abstract void drawArc( int x,int y,int width,

int height,int startAngle,int arcAngle );

. . .

}

 

Los m�todos se declaran en la clase Graphics, pero el c�digo que ejecutar� el m�todo est� en alg�n otro sitio:

 

public class MiClase extends Graphics {

public void drawLine( int x1,int y1,int x2,int y2 ) {

<c�digo para pintar l�neas -espec�fico de

la arquitectura->

}

}

 

Cuando una clase contiene un m�todo abstracto tiene que declararse abstracta. No obstante, no todos los m�todos de una clase abstracta tienen que ser abstractos. Las clases abstractas no pueden tener m�todos privados (no se podr�an implementar) ni tampoco est�ticos. Una clase abstracta tiene que derivarse obligatoriamente, no se puede hacer un new de una clase abstracta.

 

Una clase abstracta en Java es lo mismo que en C++ virtual func() = 0; lo que obliga a que al derivar de la clase haya que implementar forzosamente los m�todos de esa clase abstracta.

 

 

3.11 Interfaces

Los m�todos abstractos son �tiles cuando se quiere que cada implementaci�n de la clase parezca y funcione igual, pero necesita que se cree una nueva clase para utilizar los m�todos abstractos.

 

Los interfaces proporcionan un mecanismo para abstraer los m�todos a un nivel superior.

 

Un interface contiene una colecci�n de m�todos que se implementan en otro lugar. Los m�todos de una clase son public, static y final.

La principal diferencia entre interface y abstract es que un interface proporciona un mecanismo de encapsulaci�n de los protocolos de los m�todos sin forzar al usuario a utilizar la herencia.

 

Por ejemplo:

 

public interface VideoClip {

// comienza la reproduccion del video

void play();

// reproduce el clip en un bucle

void bucle();

// detiene la reproduccion

void stop();

}

 

Las clases que quieran utilizar el interface VideoClip utilizar�n la palabra implements y proporcionar�n el c�digo necesario para implementar los m�todos que se han definido para el interface:

 

class MiClase implements VideoClip {

void play() {

<c�digo>

}

void bucle() {

<c�digo>

}

void stop() {

<c�digo>

}

 

Al utilizar implements para el interface es como si se hiciese una acci�n de copiar-y-pegar del c�digo del interface, con lo cual no se hereda nada, solamente se pueden usar los m�todos.

 

La ventaja principal del uso de interfaces es que una clase interface puede ser implementada por cualquier n�mero de clases, permitiendo a cada clase compartir el interfaz de programaci�n sin tener que ser consciente de la implementaci�n que hagan las otras clases que implementen el interface.

 

class MiOtraClase implements VideoClip {

void play() {

<c�digo nuevo>

}

void bucle() {

<c�digo nuevo>

}

void stop() {

<c�digo nuevo>

}

 

 

3.12 M�todos Nativos

Java proporciona un mecanismo para la llamada a funciones C y C++ desde nuestro c�digo fuente Java. Para definir m�todos como funciones C o C++ se utiliza la palabra clave native.

 

public class Fecha {

int ahora;

public Fecha() {

ahora = time();

}

private native int time();

static {

System.loadLibrary( "time" );

}

}

 

Una vez escrito el c�digo Java, se necesitan ejecutar los pasos siguientes para poder integrar el c�digo C o C++:

 

 

M�s adelante trataremos en profundidad los m�todos nativos, porque a�aden una gran potencia a Java, al permitirle integrar a trav�s de librer�a din�mica cualquier algoritmo desarrollado en C o C++, lo cual, entre otras cosas, se utiliza como m�todo de protecci�n contra la descompilaci�n completa del c�digo Java.

 

3.13 Paquetes

La palabra clave package permite agrupar clases e interfaces. Los nombres de los paquetes son palabras separadas por puntos y se almacenan en directorios que coinciden con esos nombres. Por ejemplo, los ficheros siguientes, que contienen c�digo fuente Java:

 

Applet.java, AppletContext.java, AppletStub.java, AudioClip.java

 

contienen en su c�digo la l�nea:

 

package java.applet;

 

Y las clases que se obtienen de la compilaci�n de los ficheros anteriores, se encuentran con el nombre nombre_de_clase.class, en el directorio:

 

java/applet

 

Import

Los paquetes de clases se cargan con la palabra clave import, especificando el nombre del paquete como ruta y nombre de clase (es lo mismo que #include de C/C++). Se pueden cargar varias clases utilizando un asterisco.

 

import java.Date;

import java.awt.*;

 

Si un fichero fuente Java no contiene ning�n package, se coloca en el paquete por defecto sin nombre. Es decir, en el mismo directorio que el fichero fuente, y la clase puede ser cargada con la sentencia import:

 

import MiClase;

 

Paquetes de Java

El lenguaje Java proporciona una serie de paquetes que incluyen ventanas, utilidades, un sistema de entrada/salida general, herramientas y comunicaciones. En la versi�n actual del JDK, los paquetes Java que se incluyen son:

 

java.applet

Este paquete contiene clases dise�adas para usar con applets. Hay una clase Applet y tres interfaces: AppletContext, AppletStub y AudioClip.

 

java.awt

El paquete Abstract Windowing Toolkit (awt) contiene clases para generar widgets y componentes GUI (Interfaz Gr�fico de Usuario). Incluye las clases Button, Checkbox, Choice, Component, Graphics, Menu, Panel, TextArea y TextField.

 

java.io

El paquete de entrada/salida contiene las clases de acceso a ficheros: FileInputStream y FileOutputStream.

 

java.lang

Este paquete incluye las clases del lenguaje Java propiamente dicho: Object, Thread, Exception, System, Integer, Float, Math, String, etc.

 

java.net

Este paquete da soporte a las conexiones del protocolo TCP/IP y, adem�s, incluye las clases Socket, URL y URLConnection.

 

java.util

Este paquete es una miscel�nea de clases �tiles para muchas cosas en programaci�n. Se incluyen, entre otras, Date (fecha), Dictionary (diccionario), Random (n�meros aleatorios) y Stack (pila FIFO).

 

 

3.14 Referencias

Java se asemeja mucho a C y C++. Esta similitud, evidentemente intencionada, es la mejor herramienta para los programadores, ya que facilita en gran manera su transici�n a Java. Desafortunadamente, tantas similitudes hacen que no nos paremos en algunas diferencias que son vitales. La terminolog�a utilizada en estos lenguajes, a veces es la misma, pero hay grandes diferencias subyacentes en su significado.

 

C tiene tipos de datos b�sicos y punteros. C++ modifica un poco este panorama y le a�ade los tipos referencia. Java tambi�n especifica sus tipos primitivos, elimina cualquier tipo de punteros y tiene tipos referencia mucho m�s claros.

 

Todo este marem�gnum de terminolog�a provoca cierta consternaci�n, as� que vamos a intentar aclarar lo que realmente significa.

Conocemos ya ampliamente todos los tipos b�sicos de datos: datos base, integrados, primitivos e internos; que son muy semejantes en C, C++ y Java; aunque Java simplifica un poco su uso a los desarrolladores haciendo que el chequeo de tipos sea bastante m�s r�gido. Adem�s, Java a�ade los tipos boolean y hace imprescindible el uso de este tipo booleano en sentencias condicionales.

 

 

 

4. PROGRAMAS B�SICOS EN JAVA

 

 

4.1 Una m�nima aplicaci�n en java

La aplicaci�n m�s peque�a posible es la que simplemente imprimir un mensaje en la pantalla. Tradicionalmente, el mensaje suele ser "Hola Mundo!". Esto es justamente lo que hace el siguiente fragmento de c�digo:

 

//

// Aplicaci�n HolaMundo de ejemplo

//

class HolaMundoApp {

public static void main( String args[] ) {

System.out.println( "Hola Mundo!" ) ;

}

}

 

 

HolaMundo

Vamos ver en detalle la aplicaci�n anterior, l�nea a l�nea. Esas l�neas de c�digo contienen los componenetes m�nimos para imprimir Hola Mundo! en la pantalla.

 

//

// Aplicaci�n HolaMundo de ejemplo

//

 

Estas tres primera l�neas son comentarios. Hay tres tipos de comentarios en Java, // es un comentario orientado a l�nea.

 

class HolaMundoApp {

Esta l�nea declara la clase HolaMundoApp. El nombre de la clase especificado en el fichero fuente se utiliza para crear un fichero nombredeclase.class en el directorio en el que se compila la aplicaci�n. En nuestro caso, el compilador crear� un fichero llamado HolaMundoApp.class.

public static void main( String args[] ) {

 

Esta l�nea especifica un m�todo que el int�rprete Java busca para ejecutar en primer lugar. Igual que en otros lenguajes, Java utiliza una palabra clave main para especificar la primera funci�n a ejecutar. En este ejemplo tan simple no se pasan argumentos.

 

public significa que el m�todo main puede ser llamado por cualquiera, incluyendo el int�rprete Java.

static es una palabra clave que le dice al compilador que main se refiere a la propia clase HolaMundoApp y no a ninguna instancia de la clase. De esta forma, si alguien intenta hacer otra instancia de la clase, el m�todo main no se instanciar�a.

 

void indica que main no devuelve nada. Esto es importante ya que Java realiza una estricta comprobaci�n de tipos, incluyendo los tipos que se ha declarado que devuelven los m�todos.

 

args[] es la declaraci�n de un array de Strings. Estos son los argumentos escritos tras el nombre de la clase en la l�nea de comandos:

 

%java HolaMundoApp arg1 arg2 ...

 

System.out.println( "Hola Mundo!" );

 

Esta es la funcionalidad de la aplicaci�n. Esta l�nea muestra el uso de un nombre de clase y m�todo. Se usa el m�todo println() de la clase out que est� en el paquete System.

 

El m�todo println() toma una cadena como argumento y la escribe en el stream de salida est�ndar; en este caso, la ventana donde se lanza la aplicaci�n.

}

}

 

Finalmente, se cierran las llaves que limitan el m�todo main() y la clase HolaMundoApp.

 

Compilacion y Ejecucion de HolaMundo

Vamos a ver a continuaci�n como podemos ver el resultado de nuestra primera aplicaci�n Java en pantalla. Generaremos un fichero con el c�digo fuente de la aplicaci�n, lo compilaremos y utilizaremos el int�rprete java para ejecutarlo.

 

 

 

Ficheros Fuente Java

Los ficheros fuente en Java terminan con la extensi�n ".java". Crear un fichero utilizando cualquier editor de texto ascii que tenga como contenido el c�digo de las ocho l�neas de nuestra m�nima aplicaci�n, y salvarlo en un fichero con el nombre de HolaMundoApp.java. Para crear los ficheros con c�digo fuente Java no es necesario un procesador de textos, aunque puede utilizarse siempre que tenga salida a fichero de texto plano o ascii, sino que es suficiente con cualquier otro editor.

 

Compilaci�n

El compilador javac se encuentra en el directorio bin por debajo del directorio java, donde se haya instalado el JDK. Este directorio bin, si se han seguido las instrucciones de instalaci�n, deber�a formar parte de la variable de entorno PATH del sistema. Si no es as�, tendr�a que revisar la Instalaci�n del JDK. El compilador de Java traslada el c�digo fuente Java a byte-codes, que son los componentes que entiende la M�quina Virtual Java que est� incluida en los navegadores con soporte Java y en appletviewer.

 

Una vez creado el fichero fuente HolaMundoApp.java, se puede compilar con la l�nea siguiente:

 

%javac HolaMundoApp.java

 

Si no se han cometido errores al teclear ni se han tenido problemas con el path al fichero fuente ni al compilador, no deber�a aparecer mensaje alguno en la pantalla, y cuando vuelva a aparecer el prompt del sistema, se deber�a ver un fichero HolaMundoApp.class nuevo en el directorio donde se encuentra el fichero fuente.

 

Si ha habido alg�n problema, en Problemas de compilaci�n al final de esta secci�n, hemos intentado reproducir los que m�s frecuentemente se suelen dar, se pueden consultar por si pueden aportar un poco de luz al error que haya aparecido.

 

Ejecuci�n

Para ejecutar la aplicaci�n HolaMundoApp, hemos de recurrir al int�rprete java, que tambi�n se encuentra en el directorio bin, bajo el directorio java. Se ejecutar� la aplicaci�n con la l�nea:

 

%java HolaMundoApp

y deber�a aparecer en pantalla la respuesta de Java:

%Hola Mundo!

 

El s�mbolo % representa al prompt del sistema, y lo utilizaremos para presentar las respuestas que nos ofrezca el sistema como resultado de la ejecuci�n de los comandos que se indiquen en pantalla o para indicar las l�neas de comandos a introducir.

 

Problemas de compilaci�n

A continuaci�n presentamos una lista de los errores m�s frecuentes que se presentan a la hora de compilar un fichero con c�digo fuente Java, nos basaremos en errores provocados sobre nuestra m�nima aplicaci�n Java de la secci�n anterior, pero podr�a generalizarse sin demasiados problemas.

 

%javac: Command not found

 

No se ha establecido correctamente la variable PATH del sistema para el compilador javac. El compilador javac se encuentra en el directorio bin, que cuelga del directorio java, que cuelga del directorio donde se haya instalado el JDK (Java Development Kit).

 

%HolaMundoApp.java:3: Method printl(java.lang.String) not found in class java.io.PrintStream.

System.out.printl( "HolaMundo!);

^

 

 

%In class HolaMundoApp: main must be public and static

 

 

%Can�t find class HolaMundoApp

 

Este es un error muy sutil. Generalmente significa que el nombre de la clase es distinto al del fichero que contiene el c�digo fuente, con lo cual el fichero nombre_fichero.class que se genera es diferente del que cabr�a esperar. Por ejemplo, si en nuestro fichero de c�digo fuente de nuestra aplicaci�n HolaMundoApp.java colocamos en vez de la declaraci�n actual de la clase HolaMundoApp, la l�nea:

 

class HolaMundoapp {

 

se crear� un fichero HolaMundoapp.class, que es diferente del HolaMundoApp.class, que es el nombre esperado de la clase; la diferencia se encuentra en la a min�scula y may�scula.

4.2 El Visor de applets de Sun (appletviewer)

El visualizador de applets (appletviewer) es una aplicaci�n que permite ver en funcionamiento applets, sin necesidad de la utilizaci�n de un navegador World-Wide-Web como HotJava, Microsoft Explorer o Nescape. En adelante, recurriremos muchas veces a �l, ya que el objetivo del tutorial es el lenguaje Java.

 

Applet

La definici�n m�s extendida de applet, muy bien resumida por Patrick Naughton, indica que un applet es "una peque�a aplicaci�n accesible en un servidor Internet, que se transporta por la red, se instala autom�ticamente y se ejecuta in situ como parte de un documento web". Claro que as� la definici�n establece el entorno (Internet, Web, etc.). En realidad, un applet es una aplicaci�n pretendidamente corta (nada impide que ocupe m�s de un gigabyte, a no ser el pensamiento de que se va a transportar por la red y una mente sensata) basada en un formato gr�fico sin representaci�n independiente: es decir, se trata de un elemento a embeber en otras aplicaciones; es un componente en su sentido estricto.

 

Un ejemplo en otro �mbito de cosas podr�a ser el siguiente: Imaginemos una empresa, que cansada de empezar siempre a codificar desde cero, dise�a un formulario con los datos b�sicos de una persona (nombre, direcci�n, etc.). Tal formulario no es un di�logo por s� mismo, pero se podr�a integrar en di�logos de clientes, proveedores, empleados, etc.

 

El hecho de que se integre est�tica (embebido en un ejecutable) o din�micamente (int�rpretes, DLLs, etc.) no afecta en absoluto a la esencia de su comportamiento como componente con que construir di�logos con sentido aut�nomo.

 

Pues bien, as� es un applet. Lo que ocurre es que, dado que no existe una base adecuada para soportar aplicaciones industriales Java en las que insertar nuestras miniaplicaciones (aunque todo se andar�), los applets se han construido mayoritariamente, y con gran acierto comercial (parece), como peque�as aplicaciones interactivas, con movimiento, luces y sonido... en Internet.

 

Llamadas a Applets con appletviewer

Un applet es una m�nima aplicaci�n Java dise�ada para ejecutarse en un navegador Web. Por tanto, no necesita preocuparse por un m�todo main() ni en d�nde se realizan las llamadas. El applet asume que el c�digo se est� ejecutando desde dentro de un navegador.

 

El appletviewer se asemeja al m�nimo navegador. Espera como argumento el nombre del fichero html que debe cargar, no se le puede pasar directamente un programa Java. Este fichero html debe contener una marca que especifica el c�digo que cargar� el appletviewer:

 

<HTML>

<APPLET CODE=HolaMundo.class WIDTH=300 HEIGHT=100>

</APPLET>

</HTML>

 

El appletviewer crear un espacio de navegaci�n, incluyendo un �rea gr�fica, donde se ejecutar� el applet, entonces llamar� a la clase applet apropiada. En el ejemplo anterior, el appletviewer cargar� una clase de nombre HolaMundo y le permitir� trabajar en su espacio gr�fico.

 

Arquitectura de appletviewer

El appletviewer representa el m�nimo interfaz de navegaci�n. En la figura se muestran los pasos que seguir�a appletviewer para presentarnos el resultado de la ejecuci�n del c�digo de nuestra clase.

 

Esta es una visi�n simplificada del appletviewer. La funci�n principal de esta aplicaci�n es proporcionar al usuario un objeto de tipo Graphics sobre el que dibujar, y varias funciones para facilitar el uso del objeto Graphics.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Ciclo de vida de un Applet

Cuando un applet se carga en el appletviewer, comienza su ciclo de vida, que pasar�a por las siguientes fases:

 

 

 

Se crea una instancia de la clase que controla el applet. En el ejemplo de la figura anterior, ser�a la clase HolaMundo.

 

El applet se incializa.

 

El applet comienza a ejecutarse.

 

El applet empieza a recibir llamadas. Primero recibe una llamada init (inicializar), seguida de un mensaje start (empezar) y paint (pintar). Estas llamadas pueden ser recibidas as�ncronamente.

 

 

4.3 Escribir Applets Java

Para escribir applets Java, hay que utilizar una serie de m�todos, algunos de los cuales ya se hay sumariado al hablar de los m�todos del appletviewer, que es el visualizador de applets de Sun. Incluso para el applet m�s sencillo necesitaremos varios m�todos. Son los que se usan para arrancar (start) y detener (stop) la ejecuci�n del applet, para pintar (paint) y actualizar (update) la pantalla y para capturar la informaci�n que se pasa al applet desde el fichero HTML a trav�s de la marca APPLET.

 

init ( )

Esta funci�n miembro es llamada al crearse el applet. Es llamada s�lo una vez. La clase Applet no hace nada en init(). Las clases derivadas deben sobrecargar este m�todo para cambiar el tama�o durante su inicializaci�n, y cualquier otra inicializaci�n de los datos que solamente deba realizarse una vez. Deber�an realizarse al menos las siguientes acciones:

 

Carga de im�genes y sonido

El resize del applet para que tenga su tama�o correcto

Asignaci�n de valores a las variables globales

 

Por ejemplo:

 

public void init() {

if( width < 200 || height < 200 )

resize( 200,200 );

valor_global1 = 0;

valor_global2 = 100;

 

// cargaremos im�genes en memoria sin mostrarlas

// cargaremos m�sica de fondo en memoria sin reproducirla

}

 

destroy ( )

Esta funci�n miembro es llamada cuando el applet no se va a usar m�s. La clase Applet no hace nada en este m�todo. Las clases derivadas deber�an sobrecargarlo para hacer una limpieza final. Los applet multithread deber�n usar destroy() para "matar" cuanquier thread del applet que quedase activo.

 

start ( )

Llamada para activar el applet. Esta funci�n miembro es llamada cuando se visita el applet. La clase Applet no hace nada en este m�todo. Las clases derivadas deber�an sobrecargarlo para comenzar una animaci�n, sonido, etc.

 

public void start() {

estaDetenido = false;

// comenzar la reproducci�n de la m�sica

musicClip.play();

}

 

Tambi�n se puede utilizar start() para eliminar cualquier thread que se necesite.

 

stop ( )

Llamada para detener el applet. Se llama cuando el applet desaparece de la pantalla. La clase Applet no hace nada en este m�todo. Las clases derivadas deber�an sobrecargarlo para detener la animaci�n, el sonido, etc.

 

public void stop() {

estaDetenido = true;

 

if( /* �se est� reproduciendo m�sica? */ )

musicClip.stop();

}

 

resize ( int width,int height )

El m�todo init() deber�a llamar a esta funci�n miembro para establecer el tama�o del applet. Puede utilizar las variables ancho y alto, pero no es necesario. Cambiar el tama�o en otro sitio que no sea init() produce un reformateo de todo el documento y no se recomienda.

 

En el navegador Netscape, el tama�o del applet es el que se indica en la marca APPLET del HTML, no hace caso a lo que se indique desde el c�digo Java del applet.

 

width

Variable entera, su valor es el ancho definido en el par�metro WIDTH de la marca HTML del APPLET. Por defecto es el ancho del icono.

 

height

Variable entera, su valor es la altura definida en el par�metro HEIGHT de la marca HTML del APPLET. Por defecto es la altura del icono. Tanto width como height est�n siempre disponibles para que se puede chequear el tama�o del applet.

 

Podemos retomar el ejemplo de init():

 

public void init() {

if( width < 200 || height < 200 )

resize( 200,200 );

...

 

paint( Graphics g )

Se llama cada vez que se necesita refrescar el �rea de dibujo del applet. La clase Applet simplemente dibuja una caja con sombreado de tres dimensiones en el �rea. Obviamente, la clase derivada deber�a sobrecargar este m�todo para representar algo inteligente en la pantalla.

 

Para repintar toda la pantalla cuando llega un evento Paint, se pide el rect�ngulo sobre el que se va a aplicar paint() y si es m�s peque�o que el tama�o real del applet se invoca a repaint(), que como va a hacer un update(), se actualizar� toda la pantalla.

 

Podemos utilizar paint() para imprimir nuestro mensaje de bienvenida:

 

void public paint( Graphics g ) {

g.drawString( "Hola Java!",25,25 );

// Dibujaremos la im�genes que necesitemos

}

 

update( Graphics g )

Esta es la funci�n que se llama realmente cuando se necesita actualizar la pantalla. La clase Applet simplemente limpia el �rea y llama al m�todo paint(). Esta funcionalidad es suficiente en la mayor�a de los casos. De cualquier forma, las clases derivadas pueden sustituir esta funcionalidad para sus prop�sitos.

 

Podemos, por ejemplo, utilizar update() para modificar selectivamente partes del �rea gr�fica sin tener que pintar el �rea completa:

 

public void update( Graphics g ) {

if( estaActualizado )

{

g.clear(); // garantiza la pantalla limpia

repaint(); // podemos usar el m�todo padre: super.update()

}

else

// Informaci�n adicional

g.drawString( "Otra informaci�n",25,50 );

}

 

repaint()

A esta funci�n se la deber�a llamar cuando el applet necesite ser repintado. No deber�a sobrecargarse, sino dejar que Java repinte completamente el contenido del applet.

 

Al llamar a repaint(), sin par�metros, internamente se llama a update() que borrar� el rect�ngulo sobre el que se redibujar� y luego se llama a paint(). Como a repaint() se le pueden pasar par�metros, se puede modificar el rect�ngulo a repintar.

 

getParameter ( String attr )

Este m�todo carga los valores parados al applet v�a la marca APPLET de HTML. El argumento String es el nombre del par�metro que se quiere obtener. Devuelve el valor que se le haya asignado al par�metro; en caso de que no se le haya asignado ninguno, devolver� null.

 

Para usar getParameter(), se define una cadena gen�rica. Una vez que se ha capturado el par�metro, se utilizan m�todos de cadena o de n�meros para convertir el valor obtenido al tipo adecuado.

 

public void init() {

String pv;

 

pv = getParameter( "velocidad" );

if( pv == null )

velocidad = 10;

else

velocidad = Integer.parseInt( pv );

}

 

getDocumentBase ( )

Indica la ruta http, o el directorio del disco, de donde se ha recogido la p�gina HTML que contiene el applet, es decir, el lugar donde est� la hoja en todo Internet o en el disco.

 

getCodeBase ( )

Indica la ruta http, o el directorio del disco, de donde se ha cargado el c�digo bytecode que forma el applet, es decir, el lugar donde est� el fichero .class en todo Internet o en el disco.

 

print ( Graphics g )

Para imprimir en impresora, al igual que paint() se puede utilizar print(), que pintar� en la impresora el mapa de bits del dibujo.

 

5. EL DEPURADOR DE JAVA - jdb

 

 

El depurador de Java, jdb es un depurador de l�nea de comandos, similar al que Sun proporciona en sus Sistemas, dbx. Es complicado de utilizar y un tanto cr�ptico, por lo que, en principio, tiene escasa practicidad y es necesaria una verdadera emergencia para tener que recurrir a �l.

 

Trataremos por encima los comandos que proporciona el jdb, pero sin entrar en detalles de su funcionamiento, porque no merece la pena. Casi es mejor esperar a disponer de herramientas visuales para poder depurar con cierta comodidad nuestro c�digo Java.

 

Para poder utilizar el depurador, las aplicaciones Java deben estar compiladas con la opci�n de depuraci�n activada, -g. Posteriormente se puede lanzar appletviewer con la opci�n de depuraci�n, debug, y habremos puesto en marcha jdb.

 

 

5.1 Depurar HolaMundo

Hemos modificado nuestro applet de ejemplo para utilizarlo en nuestra sesi�n de ejemplo con el depurador. Se compilar�a con el comando:

 

%javac -g hm.java

 

y el contenido de nuestro applet HolaMundo modificado y guardado en el fichero hm.java ser�a el siguiente:

//

// Applet HolaMundo de ejemplo, para depurar

//

import java.awt.Graphics;

import java.applet.Applet;

 

public class hm extends Applet {

int i;

 

public void paint( Graphics g ) {

i = 10;

g.drawString( "Hola Mundo!",25,25 );

}

}

Una vez compilado, iniciamos la sesi�n lanzando el visor de applets de Sun con la opci�n de depuraci�n, utilizando el comando:

 

%appletviewer -debug hm.html

 

El fichero hm.html contiene las l�neas m�nimas para poder activar el applet, estas l�neas son las que reproducimos:

 

<html>

<applet code=hm.class width=100 height=100>

</applet>

</html>

 

Se inicia pues la sesi�n con el depurador y vamos a ir reproduciendo lo que aparece en la pantalla a medida que vamos introduciendo comandos:

 

%appletviewer -debug hm.html

Loading jdb...

0xee301bf0:class(sun.applet.AppletViewer)

>

 

 

5.2 Comando help

El comando help proporciona una lista de los comandos que est�n disponibles en la sesi�n de jdb. Esta lista es la que sigue, en donde hemos aprovechado la presencia de todos los comandos para comentar la acci�n que cada uno de ellos lleva a cabo.

 

>help

** command list **

threads [threadgroup] -- lista threads

thread <thread id> -- establece el thread por defecto

suspend [thread id(s)] -- suspende threads (por defecto, todos)

resume [thread id(s)] -- contin�a threads (por defecto, todos)

where [thread id]|all -- muestra la pila de un thread

threadgroups -- lista los grupos de threads

threadgroup <name> -- establece el grupo de thread actual

print <id> [id(s)] -- imprime un objeto o campo

dump <id> [id(s)] -- imprime toda la informaci�n del objeto

locals -- imprime las variables locales de la pila actual

classes -- lista las clases conocidas

methods <class id> -- lista los m�todos de una clase

stop in <class id>.<method> -- fija un punto de ruptura en un m�todo

stop at <class id>:<line> -- establece un punto de ruptura en una l�nea

up [n frames] -- ascender en la pila de threads

down [n frames] -- descender en la pila de threads

clear <class id>:<line> -- eliminar un punto de ruptura

step -- ejecutar la l�nea actual

cont -- continuar la ejecuci�n desde el punto de ruptura

catch <class id> -- parar por la excepci�n especificada

ignore <class id> -- ignorar la excepci�n especificada

list [line number] -- imprimir c�digo fuente

use [source file path] -- ver o cambiar la ruta del fichero fuente

memory -- informe del uso de la memoria

load <classname> - carga la clase Java a ser depurada

run <args> - comienza la ejecuci�n de la clase cargada

!! - repite el �ltimo comando

help (or ?) - lista los comandos

exit (or quit) - salir del depurador

>

 

 

5.3 Comando threadgroups

El comando threadgroups permite ver la lista de threads que se est�n ejecutando. Los grupos system y main deber�an estar siempre corriendo.

 

>threadgroups

1.(java.lang.ThreadGroup)0xee300068 system

2.(java.lang.ThreadGroup)0xee300a98 main

>

 

 

5.4 Comando threads

El comando threads se utiliza para ver la lista completa de los threads que se est�n ejecutando actualmente.

 

>threads

Group system:

1.(java.lang.Thread)0xee300098 clock handler cond

2.(java.lang.Thread)0xee300558 Idle thread run

3.(java.lang.Thread)0xee3005d0 sync Garbage Collector cond

4.(java.lang.Thread)0xee300620 Finalizer thread cond

5.(java.lang.Thread)0xee300a20 Debugger agent run

6.(java.tools.debug.BreakpointHandler)0xee300b58) Breakpoint handler cond

Group main:

7.(java.lang.Thread)0xee300048 main suspended

>

 

 

5.5 Comando run

El comando run es el que se utiliza para arrancar el appletviewer en la sesi�n de depuraci�n. Lo teclearemos y luego volveremos a listar los threads que hay en ejecuci�n.

>run

run sun.applet.AppletViewer hm.html

running...

main[1]threads

threads

Group sun.applet.AppletViewer.main:

1.(java.lang.Thread)0xee3000c0 AWT-Motif running

2.(sun.awt.ScreenUpdater)0xee302ed0 ScreenUpdater cond. Waiting

Group applet-hm.class:

3.(java.lang.Thread)0xee302f38 Thread-6 cond. Waiting

main[1]

 

El visor de applets de Sun aparecer� en la pantalla y mostrar� el conocido mensaje de saludo al Mundo. Ahora vamos a rearrancar el appletviewer con un punto de ruptura, para detener la ejecuci�n del applet, y podamos seguir mostrando los comandos disponibles en el jdb.

main[1]exit

%appletviewer -debug hm.html

Loading jdb...

0xee3009c8:class(sun.applet.AppletViewer)

>stop in hm.paint

Breakpoint set in hm.paint

>run

run sun.applet.AppletViewer hm.html

running...

Breakpoint hit: hm.paint(hm.java:9)

AWT-Motif[1]

5.6 Comando where

El comando where mostrar� la pila de ejecuci�n del applet.

 

AWT-Motif[1]where

[1]hm.paint(hm.java:9)

[2]sun.awt.motif.MComponentPeer.paint(MComponenetPeer.java:109)

[3]sun.awt.motif.MComponentPeer.handleExpose(MComponenetPeer.java:170)

AWT-Motif[1]

 

 

5.7 Comando use

El comando use nos informa del camino donde jdb va a buscar los ficheros fuentes que contienen el c�digo Java de las clases que se est�n depurando. Por defecto, utilizar� el camino que se especifique en la variable de entorno CLASSPATH.

 

AWT-Motif[1]use

/usr/local/java/classes:

AWT-Motif[1]

 

 

5.8 Comando list

El comando list mostrar� el c�digo fuente actual al comienzo del punto de ruptura que hayamos fijado.

 

AWT-Motif[1]list

9 public void paint( Graphics g ) {

10 => i = 10;

11 g.drawString( "Hola Mundo!",25,25 ) ;

12 }

13 }

AWT-Motif[1]

 

 

5.9 Comando dump

El comando dump nos permitir� ahora ver el valor del objeto g pasado desde el appletviewer.

 

AWT-Motif[1]dump g

g = (sun.awt.motif.X11Graphics)0xee303df8 {

int pData = 1342480

Color foreground = (java.awt.Color)0xee302378

Font font = (java.awt.Font)0xee302138

int originX = 0

int originY = 0

float scaleX = 1

float scaleY = 1

Image image = null

}

AWT-Motif[1]

 

 

5.10 Comando step

El comando step nos porporciona el m�todo para ejecutar la l�nea actual, que estar� siendo apuntada por el indicador si hemos utilizado el comando list.

 

AWT-Motif[1]step

Breakpoint hit: hm.paint(hm.java:11)

AWT-Motif[1]list

9 public void paint( Graphics g ) {

10 i = 10;

11 => g.drawString( "Hola Mundo!",25,25 );

12 }

13 }

AWT-Motif[1]

 

 

 

6. AWT

 

 

6.1 Introducci�n al AWT

AWT es el acr�nimo del X Window Toolkit para Java, donde X puede ser cualquier cosa: Abstract, Alternative, Awkward, Another o Asqueroso; aunque parece que Sun se decanta por Abstracto, seriedad por encima de todo. Se trata de una biblioteca de clases Java para el desarrollo de Interfaces de Usuario Gr�ficas. La versi�n del AWT que Sun proporciona con el JDK se desarroll� en s�lo dos meses y es la parte m�s d�bil de todo lo que representa Java como lenguaje. El entorno que ofrece es demasiado simple, no se han tenido en cuenta las ideas de entornos gr�ficos novedosos, sino que se ha ahondado en estructuras orientadas a eventos, llenas de callbacks y sin soporte alguno del entorno para la construcci�n gr�fica; veremos que la simple acci�n de colocar un dibujo sobre un bot�n se vuelve una tarea harto complicada. Quiz� la presi�n de tener que lanzar algo al mercado haya tenido mucho que ver en la pobreza de AWT.

 

JavaSoft, asegura que esto s�lo era el principio y que AWT ser� multi-idioma, tendr� herramientas visuales, etc. En fin, al igual que dicen los astr�logos, el futuro nos deparar� muchas sorpresas.

 

La estructura b�sica del AWT se basa en Componentes y Contenedores. Estos �ltimos contienen Componentes posicionados a su respecto y son Componentes a su vez, de forma que los eventos pueden tratarse tanto en Contenedores como en Componentes, corriendo por cuenta del programador (todav�a no hay herramientas de composici�n visual) el encaje de todas las piezas, as� como la seguridad de tratamiento de los eventos adecuados. Nada trivial.

 

No obstante y pese a ello, vamos a abordar en este momento la programaci�n con el AWT para tener la base suficiente y poder seguir profundizando en las dem�s caracter�sticas del lenguaje Java, porque como vamos a ir presentando ejemplos gr�ficos es imprescindible el conocimiento del AWT. Mientras tanto, esperemos que JavaSoft sea fiel a sus predicciones y lo que ahora veamos nos sirva de base para migrar a un nuevo y maravilloso AWT.

 

 

6.2 Interface de Usuario

La interface de usuario es la parte del programa que permite a �ste interactuar con el usuario. Las interfaces de usuario pueden adoptar muchas formas, que van desde la simple l�nea de comandos hasta las interfaces gr�ficas que proporcionan las aplicaciones m�s modernas.

 

La interface de usuario es el aspecto m�s importante de cualquier aplicaci�n. Una aplicaci�n sin un interfaz f�cil, impide que los usuarios saquen el m�ximo rendimiento del programa. Java proporciona los elementos b�sicos para construir decentes interfaces de usuario a trav�s del AWT.

Al nivel m�s bajo, el sistema operativo transmite informaci�n desde el rat�n y el teclado como dispositivos de entrada al programa. El AWT fue dise�ado pensando en que el programador no tuviese que preocuparse de detalles como controlar el movimiento del rat�n o leer el teclado, ni tampoco atender a detalles como la escritura en pantalla. El AWT constituye una librer�a de clases orientada a objeto para cubrir estos recursos y servicios de bajo nivel.

 

Debido a que el lenguaje de programaci�n Java es independiente de la plataforma en que se ejecuten sus aplicaciones, el AWT tambi�n es independiente de la plataforma en que se ejecute. El AWT proporciona un conjunto de herramientas para la construcci�n de interfaces gr�ficas que tienen una apariencia y se comportan de forma semejante en todas las plataformas en que se ejecute. Los elementos de interface proporcionados por el AWT est�n implementados utilizando toolkits nativos de las plataformas, preservando una apariencia semejante a todas las aplicaciones que se creen para esa plataforma. Este es un punto fuerte del AWT, pero tambi�n tiene la desventaja de que una interface gr�fica dise�ada para una plataforma, puede no visualizarse correctamente en otra diferente.

 

6.3 Estructura del AWT

La estructura de la versi�n actual del AWT podemos resumirla en los puntos que exponemos a continuaci�n:

 

 

 

6.4 Componentes y Contenedores

Una interface gr�fica est� construida en base a elementos gr�ficos b�sicos, los Componentes. T�picos ejemplos de estos Componentes son los botones, barras de desplazamiento, etiquetas, listas, cajas de selecci�n o campos de texto. Los Componentes permiten al usuario interactuar con la aplicaci�n y proporcionar informaci�n desde el programa al usuario sobre el estado del programa. En el AWT, todos los Componentes de la interface de usuario son instancias de la clase Component o uno de sus subtipos.

 

Los Componentes no se encuentran aislados, sino agrupados dentro de Contenedores. Los Contenedores contienen y organizan la situaci�n de los Componentes; adem�s, los Contenedores son en s� mismos Componentes y como tales pueden ser situados dentro de otros Contenedores. Tambi�n contienen el c�digo necesario para el control de eventos, cambiar la forma del cursor o modificar el icono de la aplicaci�n. En el AWT, todos los Contenedores son instancias de la clase Container o uno de sus subtipos.

 

Los Componentes deben circunscribirse dentro del Contenedor que los contiene. Esto hace que el anidamiento de Componentes (incluyendo Contenedores) en Contenedores crean �rboles de elementos, comenzando con un Contenedor en la raiz del �rbol y expandi�ndolo en sus ramas.

 

 

 

7. GRAFICOS

 

 

7.1 Objetos Gr�ficos

En p�ginas anteriores ya se ha mostrado c�mo escribir applets, c�mo lanzarlos y los fundamentos b�sicos de la presentaci�n de informaci�n sobre ellos. Ahora, pues, querremos hacer cosas m�s interesantes que mostrar texto; ya que cualquier p�gina HTML puede mostrar texto. Para ello, Java proporciona la clase Graphics, que permite mostrar texto a trav�s del m�todo drawString(), pero tambi�n tiene muchos otros m�todos de dibujo. Para cualquier programador, es esencial el entendimiento de la clase Graphics, antes de adentrarse en el dibujo de cualquier cosa en Java.

Esta clase proporciona el entorno de trabajo para cualquier operaci�n gr�fica que se realice dentro del AWT. Juega dos importantes papeles: por un lado, es el contexto gr�fico, es decir, contiene la informaci�n que va a afectar a todas las operaciones gr�ficas, incluyendo los colores de fondo y texto, la fuente de caracteres, la localizaci�n y dimensiones del rect�ngulo en que se va a pintar, e incluso dispone de informaci�n sobre el eventual destino de las operaciones gr�ficas (pantalla o imagen). Por otro lado, la clase Graphics proporciona m�todos que permiten el dibujo de primitivas, figuras y la manipulaci�n de fonts de caracteres y colores. Tambi�n hay clases para la manipulaci�n de im�genes, doble-buffering, etc.

 

Para poder pintar, un programa necesita un contexto gr�fico v�lido, representado por una instancia de la clase Graphics. Pero, como esta clase es abstracta, no se puede instanciar directamente; as� que debemos crear un componente y pasarlo al programa como un argumento a los m�todos paint() o update().

 

Los dos m�todos anteriores, paint() y update(), junto con el m�todo repaint() son los que est�n involucrados en la presentaci�n de gr�ficos en pantalla. El AWT, para reducir el tiempo que necesitan estos m�todos para realizar el repintado en pantalla de gr�ficos, tiene dos axiomas:

 

 

En la ejecuci�n del applet que aparece a continuaci�n, EjemploGraf.java, podemos observar como se realiza este proceso. Ignorar la zona de texto de la parte superior del applet de momento, y centrar la mirada en la parte coloreada. Utilizando otra ventana, tapar y destapar parte de la zona que ocupa el applet. Se observar� que solamente el trozo de applet que estaba cubierto es el que se repinta. Yendo un poco m�s all�, solamente aquellos componentes que est�n ocultos y se vuelvan a ver ser�n los que se repinten, sin tener en cuenta su posici�n dentro de la jerarqu�a de componentes.

 

 

 

 

 

 

La pantalla en Java se incrementa de izquierda a derecha y de arriba hacia abajo, tal como muestra la figura:

Los pixels de la pantalla son pues: posici�n 0 + ancho de la pantalla - 1.

En los textos, el punto de inserci�n se encuentra en la l�nea base de la primera letra.

 

 

7.2 M�todos para Dibujos

Vamos a presentar m�todos para dibujar varias figuras geom�tricas. Como estos m�todos funcionan solamente cuando son invocados por una instancia v�lida de la clase Graphics, su �mbito de aplicaci�n se restringe a los componentes que se utilicen en los m�todos paint() y update(). Normalmente los m�todos de dibujo de primitivas gr�ficas funcionan por pares: un m�todo pinta la figura normal y el otro pinta la figura rellena.

 

drawLine( x1,y1,x2,y2 )

drawRect( x,y,ancho,alto )

fillRect( x,y,ancho,alto )

clearRect( x,y,ancho.alto )

drawRoundRect( x,y,ancho,alto,anchoArco,altoArco )

fillRoundRect( x,y,ancho,alto,anchoArco,altoArco )

draw3DRect( x,y,ancho,alto,boolean elevado )

fill3DRect( x,y,ancho,alto,boolean elevado )

drawOval( x,y,ancho,alto )

fillOval( x,y,ancho,alto )

drawArc( x,y,ancho,alto,anguloInicio,anguloArco )

fillArc( x,y,ancho,alto,anguloInicio,anguloArco )

drawPolygon( int[] puntosX,int[] puntosY[],numPuntos )

fillPolygon( int[] puntosX,int[] puntosY[],numPuntos )

drawString( string s,x,y )

drawChars( char data[],offset,longitud,x,y )

drawBytes( byte data[],offset,longitud,x,y )

copyArea( xSrc,ySrc,ancho,alto,xDest,yDest )

 

7.3 M�todos para Imagenes

Los objetos Graphics pueden mostrar im�genes a trav�s del m�todo:

 

drawImage( Image img,int x,int y,ImageObserver observador );

 

Hay que tener en cuenta que el m�todo drawImage() necesita un objeto Image y un objeto ImageObserver. Podemos cargar una imagen desde un fichero de dibujo (actualmente s�lo se soportan formatos GIF y JPEG) con el m�todo getImage():

Image img = getImage( getDocumentBase(),"fichero.gif" );

 

La forma de invocar al m�todo getImage() es indicando un URL donde se encuentre el fichero que contiene la imagen que queremos presentar y el nombre de ese fichero:

getImage( URL directorioImagen,String ficheroImagen );

 

Un URL com�n para el m�todo getImage() es el directorio donde est� el fichero HTML. Se puede acceder a esa localizaci�n a trav�s del m�todo getDocumentBase() de la clase Applet, como ya se ha indicado.

 

Normalmente, se realiza el getImage() en el m�todo init() del applet y se muestra la imagen cargada en el m�todo paint(), tal como se muestra en el ejemplo siguiente:

 

public void init() {

img = getImage( getDocumentBase(),"pepe.gif" );

}

 

public void paint( Graphics g ) {

g.drawImage( img,x,y,this );

}

 

En el applet Imagen.java, podemos ver el ejemplo completo. Su ponemos en �l la existencia del fichero "Imagenes/pepe.gif":

 

import java.awt.*;

import sun.awt.image.URLImageSource;

import java.applet.Applet;

 

public class Imagen extends Applet {

Imagen pepe;

 

public void init() {

pepe = getImage( getDocumentBase(),"Imagenes/pepe.gif" );

}

 

public void paint( Graphics g ) {

g.drawString( pepe,25,25,this );

}

}

 

 

7.4 Sonido en Java

Java tambi�n posee m�todos predefinidos para reproducir sonido. El ordenador remoto no necesita tener un reproductor de audio; Java realizar� la reproducci�n (evidentemente, el ordenador remoto, en donde se ejecuta el applet, necesitar� disponer de hardware de sonido).

 

Reproducci�n de sonido

La forma m�s f�cil de reproducir sonido es a trav�s del m�todo play():

play( URL directorioSonido,String ficheroSonido );

 

o, simplemente:

 

play( URL unURLdeSonido );

 

Un URL com�n para el m�todo play() es el directorio donde est� el fichero HTML. Se puede acceder a esa localizaci�n a trav�s del m�todo getDocumentBase() de la clase Applet:

 

play( getDocumentBase(),"sonido.au" );

 

para que esto funcione, el fichero de la clase y el fichero sonido.au deber�an estar en el mismo directorio.

 

Reproducci�n Repetitiva

Se puede manejar el sonido como si de im�genes se tratara. Se pueden cargar y reproducir m�s tarde.

Para cargar un clip de sonido, se utiliza el m�todo getAudioClip():

AudoClip sonido;

sonido = getAudioClip( getDocumentBase(),"risas.au" );

 

Una vez que se carga el clip de sonido, se pueden utilizar tres m�todos:

sonido.play();

para reproducir el clip de sonido.

sonido.loop();

para iniciar la reproducci�n del clip de sonido y que entre en un blucle de reproducci�n, es decir, en una repetici�n autom�tica del clip.

sonido.stop();

para detener el clip de sonido que se encuentre en ese instante en reproducci�n.

 

 

7.5 Entrada por Rat�n

Una de las caracter�sticas m�s �tiles que ofrece Java es el soporte directo de la interactividad. La aplicaci�n puede reaccionar a los cambios producidos en el rat�n, por ejemplo, sin necesidad de escribir ninguna l�nea de c�digo para su control, solamente indicando qu� se quiere hacer cuando el rat�n haga algo.

El evento m�s com�n en el rat�n es el click. Este evento es gobernado por dos m�todos: mouseDown() (bot�n pulsado) y mouseUp() (bot�n soltado). Ambos m�todos son parte de la clase Applet, pero se necesita definir sus acciones asociadas, de la misma forma que se realiza con init() o con paint().

 

 

 

8. EXCEPCIONES EN JAVA

 

 

8.1 Manejo de Excepciones

Vamos a mostrar como se utilizan las excepciones, reconvirtiendo nuestro applet de saludo a partir de la versi�n iterativa de HolaIte.java:

 

import java.awt.*;

import java.applet.Applet;

 

public class HolaIte extends Applet {

private int i = 0;

private String Saludos[] = {

"Hola Mundo!",

"HOLA Mundo!",

"HOLA MUNDO!!"

};

 

public void paint( Graphics g ) {

g.drawString( Saludos[i],25,25 );

i++;

}

}

 

Normalmente, un programa termina con un mensaje de error cuando se lanza una excepci�n. Sin embargo, Java tiene mecanismos para excepciones que permiten ver qu� excepci�n se ha producido e intentar recuperarse de ella.

 

Vamos a reescribir el m�todo paint() de nuestra versi�n iterativa del saludo:

 

public void paint( Graphics g ) {

try {

g.drawString( Saludos[i],25,25 );

} catch( ArrayIndexOutOfBoundsException e ) {

g.drawString( "Saludos desbordado",25,25 );

} catch( Exception e ) {

// Cualquier otra excepci�n

System.out.println( e.toString() );

} finally {

System.out.println( "Esto se imprime siempre!" );

}

i++;

}

 

La palabra clave finally define un bloque de c�digo que se quiere que sea ejecutado siempre, de acuerdo a si se captur� la excepci�n o no. En el ejemplo anterior, la salida en la consola, con i=4 ser�a:

 

Saludos desbordado

�Esto se imprime siempre!

 

 

8.2 Generar Excepciones en Java

Cuando se produce un error se deber�a generar, o lanzar, una excepci�n. Para que un m�todo en Java, pueda lanzar excepciones, hay que indicarlo expresamente.

void MetodoAsesino() throws NullPointerException,CaidaException

Se pueden definir excepciones propias, no hay por qu� limitarse a las predefinidas; bastar� con extender la clase Exception y proporcionar la funcionalidad extra que requiera el tratamiento de esa excepci�n.

 

Tambi�n pueden producirse excepciones no de forma expl�cita como en el caso anterior, sino de forma impl�cita cuando se realiza alguna acci�n ilegal o no v�lida.

 

Las excepciones, pues, pueden originarse de dos modos: el programa hace algo ilegal (caso normal), o el programa expl�citamente genera una excepci�n ejecutando la sentencia throw (caso menos normal). La sentencia throw tiene la siguiente forma:

 

throw ObtejoExcepction;

 

El objeto ObjetoException es un objeto de una clase que extiende la clase Exception. El siguiente c�digo de ejemplo origina una excepci�n de divisi�n por cero:

 

class melon {

public static void main( String[] a ) {

int i=0, j=0, k;

 

k = i/j; // Origina un error de division-by-zero

}

}

 

Si compilamos y ejecutamos esta aplicaci�n Java, obtendremos la siguiente salida por pantalla:

 

> javac melon.java

> java melon

java.lang.ArithmeticException: / by zero

at melon.main(melon.java:5)

 

Las excepciones predefinidas, como ArithmeticException, se conocen como excepciones runtime.

Actualmente, como todas las excepciones son eventos runtime, ser�a mejor llamarlas excepciones irrecuperables. Esto contrasta con las excepciones que generamos expl�citamente, que suelen ser mucho menos severas y en la mayor�a de los casos podemos recuperarnos de ellas. Por ejemplo, si un fichero no puede abrirse, preguntamos al usuario que nos indique otro fichero; o si una estructura de datos se encuentra completa, podremos sobreescribir alg�n elemento que ya no se necesite.

8.3 Excepciones Predefinidas

Las excepciones predefinidas y su jerarqu�a de clases es la que se muestra en la figura:

 

Las siguientes son las excepciones predefinidas m�s frecuentes que se pueden encontrar:

 

ArithmeticException

Las excepciones aritm�ticas son t�picamente el resultado de una divisi�n por 0:

 

int i = 12 / 0;

 

NullPointerException

Se produce cuando se intenta acceder a una variable o m�todo antes de ser definido:

 

class Hola extends Applet {

Image img;

paint( Graphics g ) {

g.drawImage( img,25,25,this );

}

}

IncompatibleClassChangeException

El intento de cambiar una clase afectada por referencias en otros objetos, espec�ficamente cuando esos objetos todav�a no han sido recompilados.

 

ClassCastException

El intento de convertir un objeto a otra clase que no es v�lida.

 

y = (Prueba)x; // donde

 

x no es de tipo Prueba

 

NegativeArraySizeException

Puede ocurrir si hay un error aritm�tico al intentar cambiar el tama�o de un array.

 

OutOfMemoryException

�No deber�a producirse nunca! El intento de crear un objeto con el operador new ha fallado por falta de memoria. Y siempre tendr�a que haber memoria suficiente porque el garbage collector se encarga de proporcionarla al ir liberando objetos que no se usan y devolviendo memoria al sistema.

 

NoClassDefFoundException

Se referenci� una clase que el sistema es incapaz de encontrar.

 

ArrayIndexOutOfBoundsException

Es la excepci�n que m�s frecuentemente se produce. Se genera al intentar acceder a un elemento de un array m�s all� de los l�mites definidos inicialmente para ese array.

 

UnsatisfiedLinkException

Se hizo el intento de acceder a un m�todo nativo que no existe. Aqu� no existe un m�todo a.kk

 

class A {

native void kk();

}

 

y se llama a a.kk(), cuando deber�a llamar a A.kk().

 

InternalException

Este error se reserva para eventos que no deber�an ocurrir. Por definici�n, el usuario nunca deber�a ver este error y esta excepci�n no deber�a lanzarse.

8.4 Crear Excepciones Propias

Tambi�n podemos lanzar nuestras propias excepciones, extendiendo la clase System.exception.

Por ejemplo, consideremos un programa cliente/servidor. El c�digo cliente se intenta conectar al servidor, y durante 5 segundos se espera a que conteste el servidor. Si el servidor no responde, el servidor lanzar�a la excepci�n de time-out:

 

Cualquier m�todo que lance una excepci�n tambi�n debe capturarla, o declararla como parte de la interface del m�todo. Cabe preguntarse entonces, el porqu� de lanzar una excepci�n si hay que capturarla en el mismo m�todo. La respuesta es que las excepciones no simplifican el trabajo del control de errores. Tienen la ventaja de que se puede tener muy localizado el control de errores y no tenemos que controlar millones de valores de retorno, pero no van m�s all�.

 

 

8.5 Capturar Excepciones

Las excepciones lanzadas por un m�todo que pueda hacerlo deben recoger en bloque try/catch o

try/finally.

 

try

Es el bloque de c�digo donde se prev� que se genere una excepci�n. Es como si dij�semos "intenta estas sentencias y mira a ver si se produce una excepci�n". El bloque try tiene que ir seguido, al menos, por una cl�usula catch o una cl�usula finally

 

catch

Es el c�digo que se ejecuta cuando se produce la excepci�n. Es como si dij�semos "controlo cualquier excepci�n que coincida con mi argumento". En este bloque tendremos que asegurarnos de colocar c�digo que no genere excepciones. Se pueden colocar sentencias catch sucesivas, cada una controlando una excepci�n diferente. No deber�a intentarse capturar todas las excepciones con una sola cl�usula. Esto representar�a un uso demasiado general, podr�an llegar muchas m�s excepciones de las esperadas. En este caso es mejor dejar que la excepci�n se propague hacia arriba y dar un mensaje de error al usuario.

 

Se pueden controlar grupos de excepciones, es decir, que se pueden controlar, a trav�s del argumento, excepciones semejantes.

 

La cl�usula catch comprueba los argumentos en el mismo orden en que aparezcan en el programa.

Si hay alguno que coincida, se ejecuta el bloque. El operador instanceof se utiliza para identificar exactamente cual ha sido la identidad de la excepci�n.

 

finally

Es el bloque de c�digo que se ejecuta siempre, haya o no excepci�n. Hay una cierta controversia entre su utilidad, pero, por ejemplo, podr�a servir para hacer un log o un seguimiento de lo que est� pasando, porque como se ejecuta siempre puede dejarnos grabado si se producen excepciones y nos hemos recuperado de ellas o no.

 

Este bloque finally puede ser �til cuando no hay ninguna excepci�n. Es un trozo de c�digo que se ejecuta independientemente de lo que se haga en el bloque try.

 

Cuando vamos a tratar una excepci�n, se nos plantea el problema de qu� acciones vamos a tomar. En la mayor�a de los casos, bastar� con presentar una indicaci�n de error al usuario y un mensaje avis�ndolo de que se ha producido un error y que decida si quiere o no continuar con la ejecuci�n del programa.

 

 

8.6 Propagacion de Excepciones

La cl�usula catch comprueba los argumentos en el mismo orden en que aparezcan en el programa.

Si hay alguno que coincida, se ejecuta el bloque y sigue el flujo de control por el bloque finally (si lo hay) y concluye el control de la excepci�n.

 

Si ninguna de las cl�usulas catch coincide con la excepci�n que se ha producido, entonces se ejecutar� el c�digo de la cl�usula finally (en caso de que la haya). Lo que ocurre en este caso, es exactamente lo mismo que si la sentencia que lanza la excepci�n no se encontrase encerrada en el bloque try.

 

El flujo de control abandona este m�todo y retorna prematuramente al m�todo que lo llam�. Si la llamada estaba dentro del �mbito de una sentencia try, entonces se vuelve a intentar el control de la excepci�n, y as� continuamente.

 

Veamos lo que sucede cuando una excepci�n no es tratada en la rutina en donde se produce. El sistema Java busca un bloque try..catch m�s all� de la llamada, pero dentro del m�todo que lo trajo aqu�. Si la excepci�n se propaga de todas formas hasta lo alto de la pila de llamadas sin encontrar un controlador espec�fico para la excepci�n, entonces la ejecuci�n se detendr� dando un mensaje. Es decir, podemos suponer que Java nos est� proporcionando un bloque catch por defecto, que imprime un mensaje de error y sale.

 

No hay ninguna sobrecarga en el sistema por incorporar sentencias try al c�digo. La sobrecarga se produce cuando se genera la excepci�n.

 

Hemos dicho ya que un m�todo debe capturar las excepciones que genera, o en todo caso, declararlas como parte de su llamada, indicando a todo el mundo que es capaz de generar excepciones. Esto debe ser as� para que cualquiera que escriba una llamada a ese m�todo est� avisado de que le puede llegar una excepci�n, en lugar del valor de retorno normal. Esto permite al programador que llama a ese m�todo, elegir entre controlar la excepci�n o propagarla hacia arriba en la pila de llamadas.

 

 

 

9. Threads y Multithreading

 

Considerando el entorno multithread, cada thread (hilo, flujo de control del programa) representa un proceso individual ejecut�ndose en un sistema. A veces se les llama procesos ligeros o contextos de ejecuci�n. T�picamente, cada thread controla un �nico aspecto dentro de un programa, como puede ser supervisar la entrada en un determinado perif�rico o controlar toda la entrada/salida del disco. Todos los threads comparten los mismos recursos, al contrario que los procesos en donde cada uno tiene su propia copia de c�digo y datos (separados unos de otros). Gr�ficamente, los threads se parecen en su funcionamiento a lo que muestra la figura siguiente:

 

 

 

9.1 Flujo en Programas

 

Programas de flujo �nico

Un programa de flujo �nico o mono-hilvanado (single-thread) utiliza un �nico flujo de control (thread) para controlar su ejecuci�n. Muchos programas no necesitan la potencia o utilidad de m�ltiples flujos de control. Sin necesidad de especificar expl�citamente que se quiere un �nico flujo de control, muchos de los applets y aplicaciones son de flujo �nico. Programas de flujo m�ltiple

En nuestra aplicaci�n de saludo, no vemos el thread que ejecuta nuestro programa. Sin embargo, Java posibilita la creaci�n y control de threads expl�citamente. La utilizaci�n de threads en Java, permite una enorme flexibilidad a los programadores a la hora de plantearse el desarrollo de aplicaciones. La simplicidad para crear, configurar y ejecutar threads, permite que se puedan implementar muy poderosas y portables aplicaciones/applets que no se puede con otros lenguajes de tercera generaci�n. En un lenguaje orientado a Internet como es Java, esta herramienta es vital.

 

Si se ha utilizado un navegador con soporte Java, ya se habr� visto el uso de m�ltiples threads en Java. Habr� observado que dos applet se pueden ejecutar al mismo tiempo, o que puede desplazarla p�gina del navegador mientras el applet contin�a ejecut�ndose. Esto no significa que el applet utilice m�ltiples threads, sino que el navegador es multithreaded.

 

Las aplicaciones (y applets) multithreaded utilizan muchos contextos de ejecuci�n para cumplir su trabajo. Hacen uso del hecho de que muchas tareas contienen subtareas distintas e independientes. Se puede utilizar un thread para cada subtarea.

 

Mientras que los programas de flujo �nico pueden realizar su tarea ejecutando las subtareas secuencialmente, un programa multithreaded permite que cada thread comience y termine tan pronto como sea posible. Este comportamiento presenta una mejor respuesta a la entrada en tiempo real.

 

 

9.2 Creacion y Control de threads

 

Creaci�n de un Thread

Hay dos modos de conseguir threads en Java. Una es implementando la interface Runnable, la otra es extender la clase Thread.

 

La implementaci�n de la interface Runnable es la forma habitual de crear threads. Las interfaces proporcionan al programador una forma de agrupar el trabajo de infraestructura de una clase. Se utilizan para dise�ar los requerimientos comunes al conjunto de clases a implementar. La interface define el trabajo y la clase, o clases, que implementan la interface realizan ese trabajo. Los diferentes grupos de clases que implementen la interface tendr�n que seguir las mismas reglas de funcionamiento.

 

Hay una cuantas diferencias entre interface y clase. Primero, una interface solamente puede contener m�todos abstractos y/o variables est�ticas y finales (constantes). Las clases, por otro lado, pueden implementar m�todos y contener variables que no sean constantes. Segundo, una interface no puede implementar cualquier m�todo. Una clase que implemente una interface debe implementar todos los m�todos definidos en esa interface. Una interface tiene la posibilidad de poder extenderse de otras interfaces y, al contrario que las clases, puede extenderse de m�ltiples interfaces. Adem�s, una interface no puede ser instanciada con el operador new; por ejemplo, la siguiente sentencia no est� permitida:

 

Runnable a = new Runnable(); // No se permite

 

El primer m�todo de crear un thread es simplemente extender la clase Thread:

 

class MiThread extends Thread {

public void run() {

. . .

}

 

El ejemplo anterior crea una nueva clase MiThread que extiende la clase Thread y sobrecarga el m�todo Thread.run() por su propia implementaci�n. El m�todo run() es donde se realizar� todo el trabajo de la clase. Extendiendo la clase Thread, se pueden heredar los m�todos y variables de la clase padre. En este caso, solamente se puede extender o derivar una vez de la clase padre. Esta limitaci�n de Java puede ser superada a trav�s de la implementaci�n de Runnable:

 

public class MiThread implements Runnable {

Thread t;

public void run() {

// Ejecuci�n del thread una vez creado

}

}

 

En este caso necesitamos crear una instancia de Thread antes de que el sistema pueda ejecutar el proceso como un thread. Adem�s, el m�todo abstracto run() est� definido en la interface Runnable tiene que ser implementado. La �nica diferencia entre los dos m�todos es que este �ltimo es mucho m�s flexible. En el ejemplo anterior, todav�a tenemos oportunidad de extender la clase MiThread, si fuese necesario. La mayor�a de las clases creadas que necesiten ejecutarse como un thread , implementar�n la interface Runnable, ya que probablemente extender�n alguna de su funcionalidad a otras clases.

 

No pensar que la interface Runnable est� haciendo alguna cosa cuando la tarea se est� ejecutando. Solamente contiene m�todos abstractos, con lo cual es una clase para dar idea sobre el dise�o de la clase Thread. De hecho, si vemos los fuentes de Java, podremos comprobar que solamente contiene un m�todo abstracto:

 

package java.lang;

public interface Runnable {

public abstract void run() ;

}

 

Y esto es todo lo que hay sobre la interface Runnable. Como se ve, una interface s�lo proporciona un dise�o para las clases que vayan a ser implementadas. En el caso de Runnable, fuerza a la definici�n del m�todo run(), por lo tanto, la mayor parte del trabajo se hace en la clase Thread. Un vistazo un poco m�s profundo a la definici�n de la clase Thread nos da idea de lo que realmente est� pasando:

 

public class Thread implements Runnable {

...

public void run() {

if( tarea != null )

tarea.run() ;

}

}

...

}

 

De este trocito de c�digo se desprende que la clase Thread tambi�n implemente la interface Runnable. tarea.run() se asegura de que la clase con que trabaja (la clase que va a ejecutarse como un thread) no sea nula y ejecuta el m�todo run() de esa clase. Cuando esto suceda, el m�todo run() de la clase har� que corra como un thread.

 

Arranque de un Thread

Las aplicaciones ejecutan main() tras arrancar. Esta es la raz�n de que main() sea el lugar natural para crear y arrancar otros threads. La l�nea de c�digo:

 

t1 = new TestTh( "Thread 1",(int)(Math.random()*2000) );

 

crea un nuevo thread. Los dos argumentos pasados representan el nombre del thread y el tiempo que queremos que espere antes de imprimir el mensaje.

 

Al tener control directo sobre los threads, tenemos que arrancarlos expl�citamente. En nuestro ejemplo con:

t1.start();

 

start(), en realidad es un m�todo oculto en el thread que llama al m�todo run().

 

Manipulaci�n de un Thread

Si todo fue bien en la creaci�n del thread, t1 deber�a contener un thread v�lido, que controlaremos en el m�todo run().

 

Una vez dentro de run(), podemos comenzar las sentencias de ejecuci�n como en otros programas. run() sirve como rutina main() para los threads; cuando run() termina, tambi�n lo hace el thread. Todo lo que queramos que haga el thread ha de estar dentro de run(), por eso cuando decimos que un m�todo es Runnable, nos obliga a escribir un m�todo run().

 

En este ejemplo, intentamos inmediatamente esperar durante una cantidad de tiempo aleatoria (pasada a trav�s del constructor):

 

sleep( retardo );

 

El m�todo sleep() simplemente le dice al thread que duerma durante los milisegundos especificados. Se deber�a utilizar sleep() cuando se pretenda retrasar la ejecuci�n del thread. sleep() no consume recursos del sistema mientras el thread duerme. De esta forma otros threads pueden seguir funcionando. Una vez hecho el retardo, se imprime el mensaje "Hola Mundo!" con el nombre del thread y el retardo.

 

Suspensi�n de un Thread

Puede resultar �til suspender la ejecuci�n de un thread sin marcar un l�mite de tiempo. Si, por ejemplo, est� construyendo un applet con un thread de animaci�n, querr� permitir al usuario la opci�n de detener la animaci�n hasta que quiera continuar. No se trata de terminar la animaci�n, sino desactivarla. Para este tipo de control de thread se puede utilizar el m�todo suspend().

 

t1.suspend();

 

Este m�todo no detiene la ejecuci�n permanentemente. El thread es suspendido indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocaci�n al m�todo resume():

 

t1.resume();

 

Parada de un Thread

El �ltimo elemento de control que se necesita sobre threads es el m�todo stop(). Se utiliza para terminar la ejecuci�n de un thread:

t1.stop();

 

Esta llamada no destruye el thread, sino que detiene su ejecuci�n. La ejecuci�n no se puede reanudar ya con t1.start(). Cuando se desasignen las variables que se usan en el thread, el objeto thread (creado con new) quedar� marcado para eliminarlo y el garbage collector se encargar� de liberar la memoria que utilizaba.

 

En nuestro ejemplo, no necesitamos detener expl�citamente el thread. Simplemente se le deja terminar. Los programas m�s complejos necesitar�n un control sobre cada uno de los threads que lancen, el m�todo stop() puede utilizarse en esas situaciones.

 

Si se necesita, se puede comprobar si un thread est� vivo o no; considerando vivo un thread que ha comenzado y no ha sido detenido.

t1.isAlive();

 

Este m�todo devolver� true en caso de que el thread t1 est� vivo, es decir, ya se haya llamado a su m�todo run() y no haya sido parado con un stop() ni haya terminado el m�todo run() en su ejecuci�n.

 

 

9.3 Estados de un thread

Durante el ciclo de vida de un thread, �ste se puede encontrar en diferentes estados. La figura siguiente muestra estos estados y los m�todos que provocan el paso de un estado a otro. Este diagrama no es una m�quina de estados finita, pero es lo que m�s se aproxima al funcionamiento real de un thread .

Nuevo Thread

Cuando un thread est� en este estado, es simplemente un objeto Thread vac�o. El sistema no ha destinado ning�n recurso para �l. Desde este estado solamente puede arrancarse llamando al m�todo start(), o detenerse definitivamente, llamando al m�todo stop(); la llamada a cualquier otro m�todo carece de sentido y lo �nico que provocar� ser� la generaci�n de una excepci�n de tipo IllegalThreadStateException.

 

Ejecutable

La llamada al m�todo start() crear� los recursos del sistema necesarios para que el thread puede ejecutarse, lo incorpora a la lista de procesos disponibles para ejecuci�n del sistema y llama al m�todo run() del thread. En este momento nos encontramos en el estado "Ejecutable" del diagrama. Y este estado es Ejecutable y no En Ejecuci�n, porque cuando el thread est� aqu� no esta corriendo. Muchos ordenadores tienen solamente un procesador lo que hace imposible que todos los threads est�n corriendo al mismo tiempo. Java implementa un tipo de scheduling o lista de procesos, que permite que el procesador sea compartido entre todos los procesos o threads que se encuentran en la lista. Sin embargo, para nuestros prop�sitos, y en la mayor�a de los casos, se puede considerar que este estado es realmente un estado "En Ejecuci�n", porque la impresi�n que produce ante nosotros es que todos los procesos se ejecutan al mismo tiempo.

 

Cuando el thread se encuentra en este estado, todas las instrucciones de c�digo que se encuentren dentro del bloque declarado para el m�todo run(), se ejecutar�n secuencialmente.

 

Parado

El thread entra en estado "Parado" cuando alguien llama al m�todo suspend(), cuando se llama al m�todo sleep(), cuando el thread est� bloqueado en un proceso de entrada/salida o cuando el thread utiliza su m�todo wait() para esperar a que se cumpla una determinada condici�n. Cuando ocurra cualquiera de las cuatro cosas anteriores, el thread estar� Parado.

 

Para cada una de los cuatro modos de entrada en estado Parado, hay una forma espec�fica de volver a estado Ejecutable. Cada forma de recuperar ese estado es exclusiva; por ejemplo, si el thread ha sido puesto a dormir, una vez transcurridos los milisegundos que se especifiquen, �l solo se despierta y vuelve a estar en estado Ejecutable. Llamar al m�todo resume() mientras est� el thread durmiendo no servir�a para nada.

 

 

Los m�todos de recuperaci�n del estado Ejecutable, en funci�n de la forma de llegar al estado Parado del thread, son los siguientes:

 

Muerto

Un thread se puede morir de dos formas: por causas naturales o porque lo maten (con stop()). Un thread muere normalmente cuando concluye de forma habitual su m�todo run(). Por ejemplo, en el siguiente trozo de c�digo, el bucle while es un bucle finito -realiza la iteraci�n 20 veces y termina-:

 

El m�todo isAlive()

La interface de programaci�n de la clase Thread incluye el m�todo isAlive(), que devuelve true si el thread ha sido arrancado (con start()) y no ha sido detenido (con stop()). Por ello, si el m�todo isAlive() devuelve false, sabemos que estamos ante un "Nuevo Thread" o ante un thread "Muerto". Si nos devuelve true, sabemos que el thread se encuentra en estado "Ejecutable" o "Parado". No se puede diferenciar entre "Nuevo Thread" y "Muerto", ni entre un thread "Ejecutable" o "Parado".

 

 

9.4 Comunicacion entre threads

Otra clave para el �xito y la ventaja de la utilizaci�n de m�ltiples threads en una aplicaci�n, o aplicaci�n multithreaded, es que pueden comunicarse entre s�. Se pueden dise�ar threads para utilizar objetos comunes, que cada thread puede manipular independientemente de los otros threads.

 

El ejemplo cl�sico de comunicaci�n de threads es un modelo productor/consumidor. Un thread produce una salida, que otro thread usa (consume), sea lo que sea esa salida. Vamos entonces a crear un productor, que ser� un thread que ir� sacando caracteres por su salida; crearemos tambi�n un consumidor que ira recogiendo los caracteres que vaya sacando el productor y un monitor que controlar� el proceso de sincronizaci�n entre los threads.

Funcionar� como una tuber�a, insertando el productor caracteres en un extremos y ley�ndolos el consumidor en el otro, con el monitor siendo la propia tuber�a.

 

 

 

 

 

 

 

11.METODOS NATIVOS

 

Un m�todo nativo es un m�todo Java (una instancia de un objeto o una clase) cuya implementaci�n se ha realizado en otro lenguaje de programaci�n, por ejemplo, C. Vamos a ver c�mo se integran m�todos nativos en clases Java. Actualmente, el lenguaje Java solamente proporciona mecanismos para integrar c�digo C en programas Java.

Veamos pues los pasos necesarios para mezclar c�digo nativo C y programas Java. Recurriremos (�C�mo no!) a nuestro saludo; en este caso, el programa HolaMundo tiene dos clases Java: la primera implementa el m�todo main() y la segunda, HolaMundo, tiene un m�todo nativo que presenta el mensaje de saludo. La implementaci�n de este segundo m�todo la realizaremos en C.

 

 

10.1 Escribir C�digo Java

En primer lugar, debemos crear una clase Java, HolaMundo, que declare un m�todo nativo. Tambi�n debemos crear el programa principal que cree el objeto HolaMundo y llame al m�todo nativo.

 

Las siguientes l�neas de c�digo definen la clase HolaMundo, que consta de un m�todo y un segmento est�tico de c�digo:

 

class HolaMundo {

public native void presentaSaludo();

static {

System.loadLibrary( "hola" );

}

}

 

Podemos decir que la implementaci�n del m�todo presentaSaludo() de la clase HolaMundo est� escrito en otro lenguaje, porque la palabra reservada native aparece como parte de la definici�n del m�todo. Esta definici�n, proporciona solamente la definici�n para presentaSaludo() y no porporciona ninguna implementaci�n para �l. La implementaci�n la proporcionaremos desde un fichero fuente separado, escrito en lenguaje C.

La definici�n para presentaSaludo() tambi�n indica que el m�todo es un m�todo p�blico, no acepta argumentos y no devuelve ning�n valor. Al igual que cualquier otro m�todo, los m�todos nativos deben estar definidos dentro de una clase Java.

 

El c�digo C que implementa el m�todo presentaSaludo() debe ser compilado en una librer�a din�mica y cargado en la clase Java que lo necesite. Esta carga, mapea la implementaci�n del m�todo nativo sobre su definici�n.

 

El siguiente bloque de c�digo carga la librer�a din�mica, en este caso hola. El sistema Java ejecutar� un bloque de c�digo est�tico de la clase cuando la cargue.

 

Todo el c�digo anterior forma parte del fichero HolaMundo.java, que contiene la clase HolaMundo. En un fichero separado, Main.java, vamos a crear una aplicaci�n Java que instancie a la clase HolaMundo y llame al m�todo nativo presentaSaludo().

 

class Main {

public static void main( String args[] ) {

new HolaMundo().presentaSaludo();

}

}

 

Como se puede observar, llamamos al m�todo nativo del mismo modo que a cualquier otro m�todo Java; a�adimos el nombre del m�todo al final del nombre del objeto con un punto ("."). El conjunto de par�ntesis que sigue al nombre del m�todo encierra los argumentos que se le pasen. En este caso, el m�todo presentaSaludo() no recibe ning�n tipo de argumento.

 

 

10.2 Compilar el C�digo Java

Utilizaremos ahora el compilador javac para compilar el c�digo Java que hemos desarrollado. Compilaremos los dos ficheros fuentes de c�digo Java que hemos creado, tecleando los siguientes comandos:

> javac HolaMundo.java

> javac Main.java

 

 

 

10.3 Crear el Fichero de Cabecera

Ahora debemos utilizar la aplicaci�n javah para conseguir el fichero de cabecera .h. El fichero de cabecera define una estructura que representa la clase HolaMundo sobre c�digo C y proporciona la definici�n de una funci�n C para la implementaci�n del m�todo nativo presentaSaludo() definido en ese clase.

Ejecutamos javah sobre la clase HolaMundo, con el siguiente comando:

> javah HolaMundo

 

Por defecto, javah crear� el nuevo fichero .h en el mismo directorio en que se encuentra el fichero .class, obtenido al compilar con javac el c�digo fuente Java correspondiente a la clase. El fichero que crear�, ser� un fichero de cabecera del mismo nombre que la clase y con extensi�n .h. Por ejemplo, el comando anterior habr� creado el fichero HolaMundo.h, cuyo contenido ser� el siguiente:

 

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <native.h>

/* Header for class HolaMundo */

 

#ifndef _Included_HolaMundo

#define _Included_HolaMundo

 

typedef struct ClassHolaMundo {

char PAD; /* ANSI C requires structures to have a least one member */

} ClassHolaMundo;

HandleTo(HolaMundo);

#ifdef __cplusplus

extern "C" {

#endif

__declspec(dllexport) void HolaMundo_presentaSaludo(struct HHolaMundo *);

#ifdef __cplusplus

}

#endif

#endif

 

Este fichero de cabecera contiene la definici�n de una estructura llamada ClassHolaMundo. Los miembros de esta estructura son paralelos a los miembros de la clase Java correspondiente; es decir, los campos en la estructura corresponden a las variables de la clase. Pero como HolaMundo no tiene ninguna variable, la estructura se encuentra vac�a. Se pueden utilizar los miembros de la estructura para referenciar a variables instanciadas de la clase desde las funciones C. Adem�s de la estructura C similar a la clase Java, vemos que la llamada de la funci�n C est� declarada como:

extern void HolaMundo_presentaSaludo( struct HHolaMundo *);

 

Esta es la definici�n de la funci�n C que deberemos escribir para implementar el m�todo nativo presentaSaludo() de la clase HolaMundo. Debemos utilizar esa definici�n cuando lo implementemos. Si HolaMundo llamase a otros m�todos nativos, las definiciones de las funciones tambi�n aparecer�an aqu�.

El nombre de la funci�n C que implementa el m�todo nativo est� derivado del nombre del paquete, el nombre de la clase y el nombre del m�todo nativo. As�, el m�todo nativo presentaSaludo() dentro de la clase HolaMundo es HolaMundo_presentaSaludo(). En este ejemplo, no hay nombre de paquete porque HolaMundo se considera englobado dentro del paquete por defecto.

La funci�n C acepta un par�metro, aunque el m�todo nativo definido en la clase Java no acepte ninguno. Se puede pensar en este par�metro como si fuese la variable this de C++. En nuestro caso, ignoramos el par�metro this.

 

 

10.4 Crear el Fichero de stubs

Volvemos a utilizar la aplicaci�n javah para crear el fichero de stubs, que contiene todas las declaraciones de m�todos, con sus llamadas y argumentos, listos para que nosotros rellenemos el cuerpo de los m�todos con los algoritmos que necesitemos implementar. Proporciona la uni�n entre la clase Java y su estructura C paralela.

 

Para generar este fichero, debemos indicar el par�metro .stubs al ejecutar la aplicaci�n javah sobre la clase HolaMundo, de la siguiente forma:

 

> javah -stubs HolaMundo

 

Del mismo modo que se generaba el fichero .h; el nombre del fichero de stubs ser� el nombre de la clase con la extensi�n .c. En nuestro ejemplo, ser� HolaMundo.c, y su contenido ser� el siguiente:

 

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <StubPreamble.h>

 

/* Stubs for class HolaMundo */

/* SYMBOL: "HolaMundo/presentaSaludo()V",

Java_HolaMundo_presentaSaludo_stub */

__declspec(dllexport) stack_item

*Java_HolaMundo_presentaSaludo_stub(stack_item *_P_,struct execenv *_EE_) {

extern void HolaMundo_presentaSaludo(void *);

(void) HolaMundo_presentaSaludo(_P_[0].p);

return _P_;

}

 

 

10.5 Escribir la funcion C

Escribiremos la funci�n C para el m�todo nativo en un fichero fuente de c�digo C. La implementaci�n ser� una funci�n habitual C, que luego integraremos con la clase Java. La definici�n de la funci�n C debe ser la misma que la que se ha generado con javah en el fichero HolaMundo.h. La implementaci�n que proponemos la guardaremos en el fichero HolaImp.c, y contendr� las siguientes l�nea de c�digo:

 

#include <StubPreamble.h>

#include "HolaMundo.h>

#include <stdio.h>

 

void HolaMundo_presentaSaludo( struct HHolaMundo *this ) {

printf( "Hola Mundo, desde el Tutorial de Java\n" );

return;

}

 

Como se puede ver, la implementaci�n no puede ser m�s sencilla: hace una llamada a la funci�n printf() para presentar el saludo y sale.

En el c�digo se incluyen tres ficheros de cabecera:

StubsPreamble.h

 

Proporciona la informaci�n para que el c�digo C pueda interactuar con el sistema Java. Cuando se escriben m�todos nativos, siempre habr� que incluir este fichero en el c�digo fuente C.

HolaMundo.h

 

Es el fichero de cabecera que hemos generado para nuestra clase. Contiene la estructura C que representa la clase Java para la que estamos escribiendo el m�todo nativo y la definici�n de la funci�n para ese m�todo nativo.

stdio.h

 

Es necesario incluirlo porque utilizamos la funci�n printf() de la librer�a est�ndar de C, cuya declaraci�n se encuentra en este fichero de cabecera.

 

10.6 Crear la Libreria Din�mica

Utilizaremos el compilador C para compilar el fichero .h, el fichero de stubs y el fichero fuente .c; para crear una librer�a din�mica. Para crearla, utilizaremos el compilador C de nuestro sistema, haciendo que los ficheros HolaMundo.c y HolaImp.c generen una librer�a din�mica de nombre hola, que ser� la que el sistema Java cargue cuando ejecute la aplicaci�n que estamos construyendo.

Vamos a ver c�mo generamos esta librer�a en Unix y en Windows '95.

 

Unix

Teclearemos el siguiente comando:

 

% cc -G HolaMundo.c HolaImp.c -o libhola.so

 

En caso de que no encuentre el compilador los ficheros de cabecera, se puede utilizar el flag -I para indicarle el camino de b�squeda, por ejemplo:

 

% cc -G -I$JAVA_HOME/include HolaMundo.c HolaImp.c -o libhola.so

 

donde $JAVA_HOME es el directorio donde se ha instalado la versi�n actual del Java Development Kit.

 

Windows '95

El comando a utilizar en este caso es el siguiente:

 

c:\>cl HolaMundo.c HolaImp.c -Fhola.dll -MD -LD javai.lib

 

Este comando funciona con Microsoft Visual C++ 2.x y posteriores. Si queremos indicar al compilador donde se encuentran los ficheros de cabecera y las librer�as, tendremos que fijar dos variables de entorno:

 

c:\>SET INCLUDE=%JAVAHOME%\include;%INCLUDE%

c:\>SET LIB=%JAVAHOME%\lib;%LIB%

 

donde %JAVAHOME% es el directorio donde se ha instalado la versi�n actual del Java Development Kit.

 

 

 

10.7 Ejecutar el Programa

Y, por fin, utilizaremos el int�rprete de Java, java, para ejecutar el programa que hemos construido siguiendo todos los pasos anteriormente descritos. Si tecleamos el comando:

 

> java Main

 

obtendremos el resultado siguiente:

% Hola Mundo, desde el Tutorial de Java

 

Si no aparece este mensaje de saludo y lo que aparece en pantalla son expresiones como UnsatisfiedLinkError, es porque no tenemos fijado correctamente el camino de la librer�a din�mica que hemos generado. Este camino es la lista de directorios que el sistema Java utilizar� para buscar las librer�as que debe cargar. Debemos asegurarnos de que el directorio donde se encuentra nuestra librer�a hola reci�n creada, figura entre ellos.

 

Si fijamos el camino correcto y ejecutamos de nuevo el programa, veremos que ahora s� obtenemos el mensaje de saludo que esper�bamos.

 

Con ello, hemos visto como integrar c�digo C en programas Java. Quedan muchas cuestiones por medio, como la equivalencia de tipos entre Java y C, el paso de par�metros, el manejo de cadenas, etc. Pero eso supondr�a entrar en mucha m�s profundidad dentro de Java de la que aqu� pretendemos (por ahora).

 

 

 

11. Entrada/Salida Est�ndar

 

 

Los usuarios de Unix, y aquellos familiarizados con las l�neas de comandos de otros sistemas como DOS, han utilizado un tipo de entrada/salida conocida com�nmente por entrada/salida est�ndar. El fichero de entrada est�ndar (stdin) es simplemente el teclado. El fichero de salida est�ndar (stdout) es t�picamente la pantalla (o la ventana del terminal). El fichero de salida de error est�ndar (stderr) tambi�n se dirige normalmente a la pantalla, pero se implementa como otro fichero de forma que se pueda distinguir entre la salida normal y (si es necesario) los mensajes de error.

 

 

 

11.1 La clase System

Java tiene acceso a la entrada/salida est�ndar a trav�s de la clase System. En concreto, los tres ficheros que se implementan son:

 

Stdin

System.in implementa stdin como una instancia de la clase InputStream. Con System.in, se accede a los m�todos read() y skip(). El m�todo read() permite leer un byte de la entrada. skip( long n ), salta n bytes de la entrada.

Stdout

System.out implementa stdout como una instancia de la clase PrintStream. Se pueden utilizar los m�todos print() y println() con cualquier tipo b�sico Java como argumento.

 

Stderr

System.err implementa stderr de la misma forma que stdout. Como con System.out, se tiene acceso a los m�todos de PrintStream.

 

Vamos a ver un peque�o ejemplo de entrada/salida en Java. El c�digo siguiente, miType.java, reproduce, o funciona como la utilidad cat de Unix o type de DOS:

 

import java.io.*;

class miType {

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

int c;

int contador = 0;

 

while( (c = System.in.read() ) != '\n' )

{

contador++;

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

}

System.out.println(); // L�nea en blanco

System.err.println( "Contados "+ contador +" bytes en total." );

}

}

 

 

11.2 Clases comunes de Entrada/Salida

Adem�s de la entrada por teclado y salida por pantalla, se necesita entrada/salida por fichero, como son:

FileInputStream

DataInputStream

FileOutputStream

DataOutputStream

 

Tambi�n existen otras clases para aplicaciones m�s espec�ficas, que no vamos a tratar, por ser de un uso muy concreto:

PipedInputStream

BufferedInputStream

PushBackInputStream

StreamTokenizer

PipedOutputStream

BufferedOutputStream

 

 

 

12. FICHEROS EN JAVA

 

 

Todos los lenguajes de programaci�n tienen alguna forma de interactuar con los sistemas de ficheros locales; Java no es una excepci�n.

Cuando se desarrollan applets para utilizar en red, hay que tener en cuenta que la entrada/salida directa a fichero es una violaci�n de seguridad de acceso. Muchos usuarios configurar�n sus navegadores para permitir el acceso al sistema de ficheros, pero otros no.

 

Por otro lado, si se est� desarrollando una aplicaci�n Java para uso interno, probablemente ser� necesario el acceso directo a ficheros.

 

Antes de realizar acciones sobre un fichero, necesitamos un poco de informaci�n sobre ese fichero. La clase File proporciona muchas utilidades relacionadas con ficheros y con la obtenci�n de informaci�n b�sica sobre esos ficheros.

 

 

12.1 Creaci�n de un objeto File

Para crear un objeto File nuevo, se puede utilizar cualquiera de los tres constructores siguientes:

 

File miFichero;

miFichero = new File( "/etc/kk" );

o

miFichero = new File( "/etc","kk" );

o

File miDirectorio = new File( "/etc" );

miFichero = new File( miDirectorio,"kk" );

 

El constructor utilizado depende a menudo de otros objetos File necesarios para el acceso. Por ejemplo, si s�lo se utiliza un fichero en la aplicaci�n, el primer constructor es el mejor. Si en cambio, se utilizan muchos ficheros desde un mismo directorio, el segundo o tercer constructor ser�n m�s c�modos. Y si el directorio o el fichero es una variable, el segundo constructor ser� el m�s �til.

 

 

12.2 Ficheros de Acceso Aleatorio

A menudo, no se desea leer un fichero de principio a fin; sino acceder al fichero como una base de datos, donde se salta de un registro a otro; cada uno en diferentes partes del fichero. Java proporciona una clase RandomAccessFile para este tipo de entrada/salida.

 

Creaci�n de un Fichero de Acceso Aleatorio

Hay dos posibilidades para abrir un fichero de acceso aleatorio:

Con el nombre del fichero:

 

miRAFile = new RandomAccessFile( String nombre,String modo );

Con un objeto File:

miRAFile = new RandomAccessFile( File fichero,String modo );

 

El argumento modo determina si se tiene acceso de s�lo lectura (r) o de lectura/escritura (r/w). Por ejemplo, se puede abrir un fichero de una base de datos para actualizaci�n:

 

RandomAccessFile miRAFile;

miRAFile = new RandomAccessFile( "/tmp/kk.dbf","rw" );

 

Acceso a la Informaci�n

Los objetos RandomAccessFile esperan informaci�n de lectura/escritura de la misma manera que los objetos DataInput/DataOutput. Se tiene acceso a todas las operaciones read() y write() de las clases DataInputStream y DataOutputStream.

 

Tambi�n se tienen muchos m�todos para moverse dentro de un fichero:

long getFilePointer();

Devuelve la posici�n actual del puntero del fichero

void seek( long pos );

 

Coloca el puntero del fichero en una posici�n determinada. La posici�n se da como un desplazamiento en bytes desde el comienzo del fichero. La posici�n 0 marca el comienzo de ese fichero.

long length();

Devuelve la longitud del fichero. La posici�n length() marca el final de ese fichero.

 

Actualizaci�n de Informaci�n

Se pueden utilizar ficheros de acceso aleatorio para a�adir informaci�n a ficheros existentes:

 

miRAFile = new RandomAccessFile( "/tmp/kk.log","rw" );

miRAFile.seek( miRAFile.length() );

// Cualquier write() que hagamos a partir de este punto del c�digo

// a�adir� informaci�n al fichero

 

Vamos a ver un peque�o ejemplo, Log.java, que a�ade una cadena a un fichero existente:

import java.io.*;

 

// Cada vez que ejecutemos este programita, se incorporara una nueva

// linea al fichero de log que se crea la primera vez que se ejecuta

//

//

class Log {

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

RandomAccessFile miRAFile;

String s = "Informacion a incorporar\nTutorial de Java\n";

// Abrimos el fichero de acceso aleatorio

miRAFile = new RandomAccessFile( "/tmp/java.log","rw" );

// Nos vamos al final del fichero

miRAFile.seek( miRAFile.length() );

// Incorporamos la cadena al fichero

miRAFile.writeBytes( s );

// Cerramos el fichero

miRAFile.close();

}

}

13. COMUNICACIONES EN JAVA

 

 

13.1 Modelo de Comunicaciones con Java

En Java, crear una conexi�n socket TCP/IP se realiza directamente con el paquete java.net. A continuaci�n mostramos un diagrama de lo que ocurre en el lado del cliente y del servidor:

 

 

 

El modelo de sockets m�s simple es:

El servidor establece un puerto y espera durante un cierto tiempo (timeout segundos), a que el cliente establezca la conexi�n. Cuando el cliente solicite una conexi�n, el servidor abrir� la conexi�n socket con el m�todo accept().

El cliente establece una conexi�n con la m�quina host a trav�s del puerto que se designe en puerto# .

El cliente y el servidor se comunican con manejadores InputStream y OutputStream.

 

Hay una cuesti�n al respecto de los sockets, que viene impuesta por la implementaci�n del sistema de seguridad de Java. Actualmente, los applets s�lo pueden establecer conexiones con el nodo desde el cual se transfiri� su c�digo. Esto est� implementado en el JDK y en el int�rprete de Java de Netscape. Esto reduce en gran manera la flexibilidad de las fuentes de datos disponibles para los applets. El problema si se permite que un applet se conecte a cualquier m�quina de la red, es que entonces se podr�an utilizar los applets para inundar la red desde un ordenador con un cliente Netscape del que no se sospecha y sin ninguna posibilidad de rastreo.

13.2 Clases Utiles en Comunicaciones

Vamos a exponer otras clases que resultan �tiles cuando estamos desarrollando programas de comunicaciones, aparte de las que ya se han visto. El problema es que la mayor�a de estas clases se prestan a discusi�n, porque se encuentran bajo el directorio sun. Esto quiere decir que son implementaciones Solaris y, por tanto, espec�ficas del Unix Solaris. Adem�s su API no est� garantizada, pudiendo cambiar. Pero, a pesar de todo, resultan muy interesantes y vamos a comentar un grupo de ellas solamente que se encuentran en el paquete sun.net.

 

Socket

Es el objeto b�sico en toda comunicaci�n a trav�s de Internet, bajo el protocolo TCP. Esta clase proporciona m�todos para la entrada/salida a trav�s de streams que hacen la lectura y escritura a trav�s de sockets muy sencilla.

 

ServerSocket

Es un objeto utilizado en las aplicaciones servidor para escuchar las peticiones que realicen los clientes conectados a ese servidor. Este objeto no realiza el servicio, sino que crea un objeto Socket en funci�n del cliente para realizar toda la comunicaci�n a trav�s de �l.

 

DatagramSocket

La clase de sockets datagrama puede ser utilizada para implementar datagramas o fiables (sockets UDP), no ordenados. Aunque la comunicaci�n por estos sockets es muy r�pida porque no hay que perder tiempo estableciendo la conexi�n entre cliente y servidor.

 

DatagramPacket

Clase que representa un paquete datagrama conteniendo informaci�n de paquete, longitud de paquete, direcciones Internet y n�meros de puerto.

 

MulticastSocket

Clase utilizada para crear una versi�n multicast de las clase socket datagrama. M�ltiples clientes/servidores pueden transmitir a un grupo multicast (un grupo de direcciones IP compartiendo el mismo n�mero de puerto).

 

NetworkServer

Una clase creada para implementar m�todos y variables utilizadas en la creaci�n de un servidor TCP/IP.

 

NetworkClient

Una clase creada para implementar m�todos y variables utilizadas en la creaci�n de un cliente TCP/IP.

SocketImpl

Es un Interface que nos permite crearnos nuestro propio modelo de comunicaci�n. Tendremos que implementar sus m�todos cuando la usemos. Si vamos a desarrollar

una aplicaci�n con requerimientos especiales de comunicaciones, como pueden se la implementaci�n de un cortafuegos (TCP es un protocolo no seguro), o acceder a equipos especiales (como un lector de c�digo de barras o un GPS diferencial), necesitaremos nuestra propia clase Socket.

 

 

 

14. ARQUITECTURA Modelo/Vista/Controlador

 

 

La arquitectura MVC (Model/View/Controller) fue introducida como parte de la versi�n Smalltalk-80 del lenguaje de programaci�n Smalltalk. Fue dise�ada para reducir el esfuerzo de programaci�n necesario en la implementaci�n de sistemas m�ltiples y sincronizados de los mismos datos. Sus caracter�sticas principales son que el Modelo, las Vistas y los Controladores se tratan como entidades separadas; esto hace que cualquier cambio producido en el Modelo se refleje autom�ticamente en cada una de las Vistas.

 

Adem�s del programa ejemplo que hemos presentado al principio y que posteriormente implementaremos, este modelo de arquitectura se puede emplear en sistemas de representaci�n gr�fica de datos, como se ha citado, o en sistemas CAD, en donde se presentan partes del dise�o con diferente escala de aumento, en ventanas separadas.

 

En la figura siguiente, vemos la arquitectura MVC en su forma m�s general. Hay un Modelo, m�ltiples Controladores que manipulan ese Modelo, y hay varias Vistas de los datos del Modelo, que cambian cuando cambia el estado de ese Modelo.

 

Este modelo de arquitectura presenta varias ventajas:

Hay una clara separaci�n entre los componentes de un programa; lo cual nos permite implementarlos por separado.

 

Hay un API muy bien definido; cualquiera que use el API, podr� reemplazar el Modelo, la Vista o el Controlador, sin aparente dificultad.

La conexi�n entre el Modelo y sus Vistas es din�mica; se produce en tiempo de ejecuci�n, no en tiempo de compilaci�n.

 

Al incorporar el modelo de arquitectura MVC a un dise�o, las piezas de un programa se pueden construir por separado y luego unirlas en tiempo de ejecuci�n. Si uno de los Componentes, posteriormente, se observa que funciona mal, puede reemplazarse sin que las otras piezas se vean afectadas. Este escenario contrasta con la aproximaci�n monol�tica t�pica de muchos programas Java. Todos tienen un Frame que contiene todos los elementos, un controlador de eventos, un mont�n de c�lculos y la presentaci�n del resultado. Ante esta perspectiva, hacer un cambio aqu� no es nada trivial.

 

 

14.1 Definici�n de las partes

El Modelo es el objeto que representa los datos del programa. Maneja los datos y controla todas sus transformaciones. El Modelo no tiene conocimiento espec�fico de los Controladores o de las Vistas, ni siquiera contiene referencias a ellos. Es el propio sistema el que tiene encomendada la responsabilidad de mantener enlaces entre el Modelo y sus Vistas, y notificar a las Vistas cuando cambia el Modelo.

 

La Vista es el objeto que maneja la presentaci�n visual de los datos representados por el Modelo. Genera una representaci�n visual del Modelo y muestra los datos al usuario. Interact�a con el Modelo a trav�s de una referencia al propio Modelo.

 

El Controlador es el objeto que proporciona significado a las ordenes del usuario, actuando sobre los datos representados por el Modelo. Cuando se realiza alg�n cambio, entra en acci�n, bien sea por cambios en la informaci�n del Modelo o por alteraciones de la Vista. Interact�a con el Modelo a trav�s de una referencia al propio Modelo.

 

Vamos a mostrar un ejemplo concreto. Consideremos como tal el sistema descrito en la introducci�n a este cap�tulo, una pieza geom�trica en tres dimensiones, que representamos en la figura siguiente:

 

 

 

 

 

En este caso, la pieza central de la escena en tres dimensiones es el Modelo. El Modelo es una descripci�n matem�tica de los v�rtices y las caras que componen la escena. Los datos que describen cada v�rtice o cara pueden modificarse (quiz�s como resultado de una acci�n del usuario, o una distorsi�n de la escena, o un algoritmo de sombreado). Sin embargo, no tiene noci�n del punto de vista, m�todo de presentaci�n, perspectiva o fuente de luz. El Modelo es una representaci�n pura de los elementos que componen la escena.

 

La porci�n del programa que transforma los datos dentro del Modelo en una presentaci�n gr�fica es la Vista. La Vista incorpora la visi�n del Modelo a la escena; es la representaci�n gr�fica de la escena desde un punto de vista determinado, bajo condiciones de iluminaci�n determinadas.

 

El Controlador sabe que puede hacer el Modelo e implementa el interface de usuario que permite iniciar la acci�n. En este ejemplo, un panel de datos de entrada es lo �nico que se necesita, para permitir a�adir, modificar o borrar v�rtices o caras de la figura.

 



Especial de Monografias.com - 
Aprenda Mecanografia Gratis!
w w w . m o n o g r a f i a s . c o m