Está en la página 1de 87

INTRODUCCIN A LA PROGRAMACIN EN JAVA

1. INTRODUCCIN
1.1. Entorno de desarrollo Java
1.1.1. El compilador Java y la Java Virtual Machine
1.1.2. Variables PATH y CLASSPATH
1.1.3. Ejemplos
1.2. Nomenclatura y estructura de un programa Java
2. PROGRAMACIN EN JAVA
2.1. Tipos y nombres de variables. Tipos Primitivos
2.1.1. Definicin, inicializacin, visibilidad y vida
2.1.2. Clases BigInteger y BigDecimal
2.2. Operadores y precedencia
2.3. Estructuras de control
2.3.1. Bifurcaciones
2.3.2. Bucles
2.3.2.1. While y Do while
2.3.2.2. For
2.3.2.3. Break, continue y return
2.3.3. Try, catch, finally
3. CLASES EN JAVA
3.1. Variables
3.2. Mtodos (funciones miembro)
3.2.1. Mtodos de objeto
3.2.1.1. Sobrecarga de mtodos
3.2.1.2. Paso de argumentos a mtodos
3.2.2. Mtodos de clase (static)
3.3. Objetos. Creacin, destruccin y finalizadores
3.4. Packages
3.5. Herencia
3.5.1. Clases y mtodos abstractos. Constructores en clases derivadas
3.5.2. Interfaces
3.7. Clases internas
3.7.1. Clases e interfaces internas static
3.7.2. Clases internas miembro (no static)
3.7.3. Clases internas locales y clases annimas
3.8. Permisos de acceso en java
3.9. Transformaciones de tipo: casting
3.10. Polimorfismo

Programacin en Java 1
4. CLASES DE UTILIDAD
4.1. Arrays
4.2. Clases string y stringbuffer
4.3. Wrappers y clase Math
4.4. Colecciones
4.4.1. Clase Vector, Hashtable e interface Enumeration
4.4.2. Collections Framework Java 1.2
4.4.2.1. Interfaces Collection, Iterator y ListIterator
4.4.2.2. Interfaces Comparable y Comparator
4.4.2.3. Sets y SortedSets
4.4.2.4. Listas
4.4.2.5. Maps y SortedMaps
4.4.2.6. Clases Collections y Arrays
4.4.2.7. Clases abstract e interfaces Cloneable y Serializable
4.5. Otras clases del package java.util
4.5.1. Clase Date, Calendar y GregorianCalendar
4.5.2. Clases DateFormat, SimpleDateFormat, TimeZone y SimpleTimeZone
5. EL AWT (ABSTRACT WINDOWS TOOLKIT)
5.1. Componentes y eventos del AWT Java
5.1.1. Relacin entre Componentes y Eventos
5.1.2. Interfaces Listener y Clases Adapter
5.2. Clase Component
5.2.1. Clase Container
5.2.1.1. Clase Panel y ScrollPane
5.2.1.2. Clase Window, Frame, Dialog y FileDialog
5.2.2. Clases Button, Canvas, Checkbox y CheckboxGroup
5.2.3. Clases Choice, Label, List y Scrollbar
5.2.4. Clases TextComponent, TextArea y TextField
5.3. Clases EventObject y AWTEvent
5.3.1. Clases ActionEvent, Adjustment Event, ItemEvent y TextEvent
5.3.2. Clase ComponentEvent
5.3.2.1. Clases ContainerEvent, FocusEvent y WindowEvent
5.3.2.2. Clases InputEvent, MouseEvent y KeyEvent
5.4. Mens
5.4.1 Clase MenuShortcut, MenuComponent, MenuBar, MenuItem y Menu
5.4.2 Clase CheckboxMenuItem y PopupMenu
5.5. Layout managers
5.5.1. FlowLayout
5.5.2. BorderLayout, GridLayout, CardLayout y GridBagLayout
5.6. Grficos, texto e imgenes
5.6.1. Clase Graphics y Font

Programacin en Java 2
5.6.2. Clase FontMetrics y Color
5.6.3. Imgenes
5.7. Animaciones
6. THREADS
6.1. Ciclo de vida de un thread
6.2. Sincronizacin y prioridad
6.3. Grupos de Threads
7. APPLETS
7.1. Inclusin de un applet en una pgina html y paso de parmetros
7.2. Carga de applets
7.3. Imagen y sonido en applets
7.4. Obtencin de las propiedades del sistema y uso de threads
8. EXCEPCIONES
8.1. Lanzamiento y captura de excepciones
8.2. Creacin de nuevas excepciones y trato con herencia
9. E/S DE DATOS
9.1. Nomenclatura de las clases de java.io
9.2. E/S estndar
9.2.1. Salida de texto y variables por pantalla
9.2.2. Lectura del teclado
9.3. Lectura y escritura de archivos
9.3.1. Clases file y filedialog
9.3.2. Lectura y escritura de archivos de texto
9.3.3. Archivos no de texto
9.4. Serializacin
9.5. Lectura de un archivo en un servidor de Internet
10. OTRAS CAPACIDADES DE JAVA
10.1. Java Foundation Classes (JFC) y Java 2D
10.2. Java Media Framework (JMF) y Java 3D
10.3. Javabeans
10.4. Java en la red. Servlets, RMI y Java IDL
10.5. Seguridad en Java
10.6. Acceso a bases de datos (JDBC)
10.7. Java Native Interface (JNI)

Programacin en Java 3
1. INTRODUCCIN
Java surgi en 1991. Un grupo de ingenieros de Sun disearon un lenguaje de programacin destinado a
electrodomsticos. La reducida potencia de clculo y memoria de los electrodomsticos llev a desarrollar
un lenguaje sencillo capaz de generar cdigo de tamao reducido.
La variedad distintas CPUs y su evolucin obligaba a una herramienta independiente. Desarrollaron un
cdigo neutro que se ejecutaba sobre una mquina virtual, la Java Virtual Machine (JVM). La JVM
interpretaba el cdigo neutro convirtindolo a cdigo particular de la CPU en cuestin. Esto permita lo que
luego se ha convertido en el lema del lenguaje: Write Once, Run Everywhere.
Ninguna empresa de electrodomsticos se interes por el nuevo lenguaje y como lenguaje de programacin
se introdujo a finales de 1995. La clave fue la incorporacin de un intrprete Java en la versin 2.0 del
programa Netscape Navigator, produciendo una revolucin en Internet. Java 1.1 apareci a principios de
1997, mejorando su primera versin. Java 1.2, ms tarde rebautizado como Java 2, naci a finales de 1998.
Al programar en Java no se parte de cero. Cualquier aplicacin se apoya, en un gran nmero de clases
preexistentes. Algunas de ellas las ha podido crear el propio usuario, otras pueden ser comerciales, pero
siempre abundantes, que forman parte del propio lenguaje (el API o Application Programming Interface).
Java incorpora muchos aspectos que en cualquier otro lenguaje son extensiones propiedad de empresas de
sw o fabricantes de ordenadores (threads, ejecucin remota, seguridad, acceso a BBDD, etc.). Por eso
muchos expertos opinan que Java es el lenguaje ideal para aprender la informtica moderna, porque
incorpora estos conceptos de un modo estndar, ms sencillo que con extensiones de otros lenguajes. Es
consecuencia de haber sido diseado ms recientemente y por un nico equipo.
El objetivo de Java es llegar a ser el nexo universal que conecte a los usuarios con la informacin, est en
local, en un servidor, BBDD u otro lugar. Java es un lenguaje completo: Java 1.0 tena 12 packages; Java
1.1 tena 23 y Java 1.2 tiene 59. En cierta forma casi todo depende de casi todo. Por ello, conviene
aprenderlo de modo iterativo: primero una visin general, que se vaya refinando en realimentacin. Una
forma es empezar con un ejemplo completo en que aparecen las caractersticas importantes.
Sun describe Java como simple, orientado a objetos (OO), distribuido, interpretado, robusto, seguro, de
arquitectura neutra, portable, de altas prestaciones, multitarea y dinmico.
Java 2 (antes Java 1.2 o JDK 1.2) es su tercera versin importante. No hay cambios conceptuales, sino
extensiones y ampliaciones. A efectos es casi lo mismo trabajar con Java 1.1 o Java 1.2. Los desarrollos en
Java presentan ventajas frente a los de otros lenguajes como C/C++. La ejecucin de programas en Java
tiene muchas posibilidades: ejecucin como aplicacin independiente (Stand-alone Application); como
applet; como servlet, etc. La ejecucin como aplicacin independiente es anloga a los programas
tradicionales. Un applet es una aplicacin que se ejecuta en un navegador al cargar una pgina HTML. Se
descarga del servidor y no requiere instalacin en el cliente. Un servlet es una aplicacin sin interface
grfica que se ejecuta en un servidor.
Adems de incorporar la ejecucin como Applet, Java permite el desarrollo fcil tanto de arquitecturas
cliente-servidor como de aplicaciones distribuidas, consistentes en aplicaciones que se conectan a otras
mquinas y ejecutan tareas en varios equipos simultneamente, repartiendo por tanto el trabajo. Aunque
tambin otros lenguajes de programacin permiten crear aplicaciones de este tipo, Java incorpora en su API
estas funcionalidades.
1.1. Entorno de desarrollo Java
Existen varios entornos de desarrollo Java comerciales. Sun distribuye gratuitamente el Java Development
Kit (JDK). Es una suite y bibliotecas que permiten desarrollar, compilar y ejecutar programas Java. Incorpora
la posibilidad de ejecutar parcialmente el programa, deteniendo la ejecucin en el punto deseado y
estudiando en cada momento el valor de cada variable (el Debugger). Existe una versin reducida del JDK,
denominada JRE (Java Runtime Environment) destinada slo a ejecutar cdigo Java (no permite compilar).
Los IDEs (Integrated Development Environment) son entornos de desarrollo integrados. En un mismo
programa es posible escribir cdigo Java, compilarlo y ejecutarlo. Algunos incluyen una herramienta de
Debug grfico, frente a la versin del JDK basada en CLI. Estos IDE permiten desarrollar aplicaciones de
forma rpida, incorporando bibliotecas de componentes. Como inconvenientes se pueden sealar fallos de
compatibilidad entre plataformas, y ficheros de mayor tamao que los basados en clases estndar.
1.1.1. El compilador Java y la Java Virtual Machine
El compilador Java es una herramienta de desarrollo incluida en el JDK. Realiza un anlisis de sintaxis del
cdigo fuente (.java). Si no encuentra errores en el cdigo genera los ficheros compilados (.class) y en caso

Programacin en Java 4
contrario muestra las lneas errneas. En el JDK de Sun el compilador se llama javac.exe. Tiene opciones
que varan de una versin a otra.
La JVM o Java Virtual Machine. Es el sw que interpreta el cdigo convirtindolo a cdigo mquina particular
de la CPU. As se consigue independencia (abstraccin) de la mquina y el sw. La condicin es que una vez
compilado, el cdigo no debe necesitar modificaciones por cambiar de mquina o CPU. La idea es que el
cdigo se ejecuta sobre una mquina virtual, la JVM.
La JVM es el intrprete de Java. Ejecuta los bytecodes o ficheros compilados de extensin .class. Tiene
opciones entre las que destaca la posibilidad de usar el denominado JIT (Just-In-Time Compiler), que puede
mejorar entre 10 y 20 veces la velocidad de ejecucin de un programa.
1.1.2. Variables PATH y CLASSPATH
PATH. Es una variable de entorno que el SO que indica los directorios donde se buscarn los ejecutables
no invocados con una ruta dada. El desarrollo y ejecucin de aplicaciones Java exige que las herramientas
para compilar (javac.exe) y ejecutar (java.exe) sean accesibles. Por tanto, para compilar o ejecutar cdigo
Java, el directorio donde se encuentran los programas (javac.exe y java.exe) debe encontrarse en PATH.
CLASSPATH. Es una variable de entorno usada por Java que determina dnde buscar clases o bibliotecas
de Java (el API) y otras clases de usuario. A partir de la versin 1.1.4 del JDK no es necesario indicar esta
variable, salvo que se deseen aadir clases de usuario no incluidas en JDK. CLASSPATH puede incluir la
ruta de directorios o ficheros .zip o .jar (ficheros comprimidos de archivos .class.) en los que se encuentren
los .class. En el caso de .zip, los ficheros en l incluidos no deben estar comprimidos; con .jar la
herramienta jar.exe, de JDK, permite generar estos ficheros a partir de los archivos compilados .class.
Una forma general de indicar estas dos variables es crear un fichero batch MS-DOS (.bat) donde se
indiquen los valores de las variables. Cada vez que se abra una ventana MS-DOS ser necesario ejecutar
el fichero .bat para asignar bien estos valores.
Un posible fichero llamado set JAVAPATH=C:\jdk1.1.7
jdk117.bat, podra ser como se
set PATH=.;%JAVAPATH%\bin;%PATH%
muestra en el ejemplo; vlido si el
JDK estuviera situado en C:\jdk1.1.7. set CLASSPATH=.\;%JAVAPATH%\lib\classes.zip;%CLASSPATH%
Si no se desea tener que ejecutar este fichero cada vez que se abre una consola MS-DOS es necesario
indicar estos cambios de forma permanente, por ejemplo modificando Autoexec.bat situado en C:\,
aadiendo las lneas mostradas. Una vez reiniciado el equipo estarn presentes en cualquier consola MS2
que se cree. La modificacin al fichero Autoexec.bat incluir en la tercera lnea la ruta de los ficheros donde
estn las clases Java. En el caso de WS NT se aadir la variable PATH en el cuadro de dilogo que se
abre desde el Panel de Control > System > Environment > User Variables for NombreUsuario.
Tambin es posible usar la opcin classpath en el momento de llamar al compilador javac.exe o al
intrprete java.exe. En este caso los .jar deben indicarse con su nombre completo en CLASSPATH: no
basta poner el PATH o directorio en que se encuentra. Por ejemplo, para compilar y ejecutar el fichero
ContieneMain.java con la biblioteca de clases G:\MyProject\OtherClasses.jar, adems de las incluidas en el
CLASSPATH, la forma de compilar y ejecutar sera:
javac -classpath .\;G:\MyProject\OtherClasses.jar ContieneMain.java
java -classpath .\;G:\MyProject\OtherClasses.jar ContieneMain
Para cada versin JDK habr que tener en cuenta las variaciones. Cuando un fichero .java se compila y en
el directorio ya existe un fichero .class, se comparan las fechas de ambos ficheros. Si el .java es ms
antiguo que el .class no se produce un nuevo fichero .class. Esto slo es vlido para ficheros .class que se
corresponden con una clase public.
1.1.3. Ejemplos
El siguiente ejemplo muestra las
caractersticas centrales de Java. Las
sentencias se numeran para hacer
ms fcil la referencia al cdigo.
La ejecucin del programa imprime
algunas lneas en la consola MS-DOS
y conduce a crear la ventana mostrada
en la figura.

Programacin en Java 5
El programa principal, contenido en el fichero Ejemplo1.java, slo usa la clase Geometra y sus clases
derivadas. Es un programa puramente usuario, a pesar de lo cual hay que definirlo en una clase, como
todo programa en Java.
La lnea 1 es un comentario con 1. // fichero Ejemplo1.java
el nombre del fichero. El
2. import java.util.ArrayList;
compilador ignora lo que va
desde los // al final de lnea. 3. import java.awt.*;
Las sentencias 2 y 3 importan 4. class Ejemplo1 {
clases de los packages de
5. public static void main(String arg[]) throws InterruptedException
Java; hacen posible acceder a
dichas clases usando nombres 6. {
cortos. Por ejemplo, se puede
acceder a la clase ArrayList 7. System.out.println("Comienza main()...");
slo con el nombre ArrayList en 8. Circulo c = new Circulo(2.0, 2.0, 4.0);
lugar de con java.util.ArrayList.
9. System.out.println("Radio = " + c.r + " unidades.");
Un package es una agrupacin
de clases con una finalidad 10. System.out.println("Centro = (" + c.x + "," + c.y + ") unidades.");
relacionada. Hay una jerarqua 11. Circulo c1 = new Circulo(1.0, 1.0, 2.0);
de packages reflejada en
nombres compuestos 12. Circulo c2 = new Circulo(0.0, 0.0, 3.0);
separados por un punto. 13. c = c1.elMayor(c2);
Es habitual nombrar los 14. System.out.println("El mayor radio es " + c.r + ".");
packages con letras minsculas
(como java.util o java.awt), 15. c = new Circulo(); // c.r = 0.0;
mientras que los nombres de 16. c = Circulo.elMayor(c1, c2);
las clases suelen empezar por
mayscula (ArrayList). 17. System.out.println("El mayor radio es " + c.r + ".");

En la sentencia 3, el asterisco 18. VentanaCerrable ventana =


indica que se importan todas las 19. new VentanaCerrable("Ventana abierta al mundo...");
clases del package. El package,
java.lang, se importa siempre 20. ArrayList v = new ArrayList();
automticamente, pudindose 21. CirculoGrafico cg1 = new CirculoGrafico(200, 200, 100, Color.red);
usar sus clases directamente,
sin importar el package. 22. CirculoGrafico cg2 = new CirculoGrafico(300, 200, 100, Color.blue);
La sentencia 4 indica que se 23. RectanguloGrafico rg = new
comienza a definir la clase 24. RectanguloGrafico(50, 50, 450, 350, Color.green);
Ejemplo1. La definicin va entre
llaves {}. Como hay otras 25. v.add(cg1);
construcciones que van entre
26. v.add(cg2);
llaves, es habitual sangrar el
cdigo, para facilitar su lectura. 27. v.add(rg);
En Java todo son clases: no se 28. PanelDibujo mipanel = new PanelDibujo(v);
puede definir una variable o
29. ventana.add(mipanel);
funcin fuera de una clase. En
este caso, la clase Ejemplo1 30. ventana.setSize(500, 400);
tiene como nica finalidad
31. ventana.setVisible(true);
acoger al mtodo main(); el
programa principal del ejemplo. 32. System.out.println("Termina main()...");
Las clases usadas por main() 33. } // fin de main()
son ms importantes que la
34. } // fin de class Ejemplo1
propia clase Ejemplo1.
Una clase es una agrupacin de datos y mtodos para manejarlos y comunicarse con otras clases. As,
puede entenderse una clase como un tipo de dato creado por el usuario y un objeto como una variable
de ese tipo de clase. As, un objeto, posee la estructura de su clase; su copia propia de los datos y mtodos
definidos abstractamente en la clase.
Las lneas 5-33 son la definicin del programa principal, que en Java se llama main(). La ejecucin siempre
comienza por el mtodo main().

Programacin en Java 6
Public indica que la funcin puede ser usada por cualquier clase.
Static indica que un mtodo de clase: que puede ser usado aunque no se cree ningn objeto de la clase.
Void indica que el mtodo no tiene valor de retorno.
A continuacin de main aparecen entre parntesis los parmetros del mtodo. En el caso de main() es
siempre un vector o array (por los corchetes []), en este caso llamado arg, de cadenas de caracteres
(objetos de la clase String). Estos parmentros se pasan al programa al comenzar la ejecucin.
En las lneas 6-33 se define el cuerpo (body) del mtodo main, tambin entre llaves. Un conjunto de
sentencias entre llaves se suele llamar bloque. Los bloques no pueden entrecruzarse; un bloque puede
contener a otro, pero no se puede cerrar un bloque exterior antes de cerrar el interior.
La sentencia 7 (System.out.println("Comienza main()...");) imprime una cadena de caracteres en la salida
estndar del sistema (normalmente una ventana de CLI o especial del entorno de programacin). El mtodo
println() est asociado con una variable static llamada out, de la clase System (del package java.lang). Una
variable miembro static (variable de clase) es nica para toda la clase y existe aunque no se instancie
ningn objeto de la clase. La variable out es una variable static de la clase System. Todas las sentencias
terminan con el carcter punto y coma.
La sentencia 8 (Circulo c = new Circulo(2.0, 2.0, 4.0);) crea un objeto de la clase Circulo, que se define
posteriormente. Equivale a las sentencias Circulo c; c = new Circulo(2.0, 2.0, 4.0);. Primero se define un
objeto llamado c de clase Circulo. Con el operador new se crea el objeto c. Poir tanto, dos acciones:
definicin y creacin (con new). El nombre de la clase va seguido por tres argumentos entre parntesis, que
se pasan al constructor de la clase como datos concretos para crear el objeto (en este caso las dos
coordenadas del centro y el radio).
La diferencia entre clase y objeto aqu, responde a que la clase Circulo es lo genrico, lo abstracto; el patrn
o modelo para crear crculos concretos. El objeto c es un crculo concreto, con su centro y radio. De la clase
Circulo se pueden crear tantos objetos como se desee. La clase indica que cada objeto necesita 3 datos
(coordenadas del centro y radio), las variables miembro de la clase. Otra similitud: la clase sera el ADN, o
la especie y el objeto el individuo.
La sentencia 9 (System.out.println("Radio = " + c.r + " unidades.");) imprime en la salida estndar una
cadena de texto que contiene el valor del radio. La cadena tiene 3 partes concatenadas con el operador +.
Para acceder al radio del objeto c, se usa su nombre, seguido de punto y la variable miembro r, en la forma
[c.r], similar al formato [registro.campo]. El valor numrico del radio se convierte automticamente en
cadena de caracteres. La sentencia 10 es similar a la 9, imprimiendo las coordenadas del centro del crculo.
Las sentencias 11 y 12 crean 2 nuevos objetos (2 crculos) llamados c1 y c2.
La sentencia 13 (c = c1.elMayor(c2);) usa el mtodo elMayor() de la clase Circulo. El mtodo, se supone,
compara los radios de dos crculos y devuelve el de mayor radio, asignndose al crculo c, creado en la
sentencia 8. Todos los mtodos de Java (excepto los de clase o static) se aplican a un objeto con el
operador punto (por ejemplo, c1.elMayor()). El otro objeto (c2) se pasa como argumento entre parntesis.
Obsrvese la forma asimtrica en que se pasan los argumentos al mtodo elMayor(). De ordinario se
llama parmetro implcito a c1 y parmetro explcito a c2.
La sentencia 14 imprime el resultado de la comparacin y la sentencia 15 crea un nuevo objeto tipo Circulo
guardndolo en la referencia c. En este caso no se pasan argumentos al constructor. Eso quiere decir que
se usarn valores por defecto para el centro y radio. Esta sentencia anula o borra el resultado de la
comparacin de la lnea 13.
La sentencia 16 vuelve a usar el mtodo elMayor() para comparar 2 crculos. No es el mismo mtodo de la
sentencia 13; es otro mtodo de mismo nombre. Los mtodos diferentes (porque tienen distinto cdigo) e
igual nombre, se dice que estn sobrecargados (overloaded).
Los mtodos sobrecargados se diferencian por nmero y tipo de sus argumentos. El de la sentencia 13
tiene un nico argumento. El de la sentencia 16 tiene 2. El mtodo de la sentencia 16 es un mtodo static
(mtodo de clase) que no necesita ningn objeto como argumento implcito. Los mtodos static suelen ir
precedidos por el nombre de la clase y el operador punto (sen permite que vayan precedidos por el nombre
de cualquier objeto, pero ofusca la nomenclatura). La sentencia 16 es equivalente a la sentencia 13, pero el
mtodo static de la sentencia 16 es ms simtrico. La sentencia 17 ya se puede entender.
Las sentencias 18-31 se refieren a la parte grfica. Las lneas 18-19 crean una ventana para dibujar sobre
ella. Una ventana es un objeto de la clase Frame, del package java.awt. La clase VentanaCerrable,
explicada ms adelante, aade a la clase Frame la capacidad de responder a los eventos que provocan el

Programacin en Java 7
cierre de una ventana. La cadena que se le pasa como argumento es el ttulo que aparecer en la ventana
(como en la figura anterior).
En la sentencia 20 (ArrayList v = new ArrayList();) se crea un objeto de la clase ArrayList (del package
java.util), que permite almacenar referencias a objetos de distintas clases. En este caso se usar para
almacenar referencias a varias figuras geomtricas diferentes. Las sentencias 21-27 crean objetos grficos
y los guardan en la lista v para ser dibujados ms tarde en el objeto mipanel de la clase PanelDibujo. Los
objetos de la clase Circulo creados no eran objetos aptos para ser dibujados, pues slo tenan informacin
del centro y el radio, sin color de lnea. Las clases RectanguloGrafico y CirculoGrafico, derivan
respectivamente de las clases Rectangulo y Circulo, que se ven luego, heredando variables y mtodos y
aadiendo la informacin y mtodos necesarios para su manejo.
Las sentencias 21-22 definen 2 objetos de la clase CirculoGrafico. A las coordenadas del centro y al radio
se une el color de lnea. En la sentencia 23-24 se define un objeto de clase RectanguloGrafico, cpm im color
y las coordenadas de los vrtices superior izquierdo e inferior derecho. En las sentencias 25-27 los objetos
grficos se aaden al objeto v de la clase ArrayList con el mtodo add() de la clase. La sentencia 28
(PanelDibujo mipanel = new PanelDibujo(v);) crea un objeto de la clase PanelDibujo. Los objetos de dicha
clase son paneles; superficies en las que dibujar. Al constructor de PanelDibujo se le pasa como argumento
el vector v con las referencias de los objetos a dibujar. La sentencia 29 incluye el panel en la ventana y la
sentencia 30 establece el tamao de la ventana en pixels;
La sentencia 31 (ventana.setVisible(true);) hace visible la ventana creada. Para dibujar todo la clase
PanelDibujo derivada de la clase Container a travs de Panel, redefine el mtodo paint() de Container. En
este mtodo, explicado posteriormente, se dibujan los objetos grficos creados. El usuario no se preocupa
de llamar al mtodo paint(), pues se llama automticamente cada vez que el SO lo solicita. La figura anterior
muestra la ventana resultante de la ejecucin del programa main() de la clase Ejemplo1.
La clase Geometria es la ms importante en el sentido de que las dems clases derivan de ella. La figura
anterior muestra la jerarqua de clases del ejemplo. En Java la clase base es siempre la clase Object.
Siempre que no se diga explcitamente que una clase deriva de otra, deriva implcitamente de la clase
Object (del package java.lang). De las clases Rectangulo y Circulo derivan respectivamente las clases
RectanguloGrafico y CirculoGrafico. En ambos casos aparece el elemento Dibujable. En trminos Java, es
un interface. Se suelen usar los trminos super-clase y sub-clase para referirse a una clase padre o hija.
As Geometra es una super-clase de Circulo, mientras que 1. // fichero Geometria.java
CirculoGrafico es una sub-clase. En este ejemplo slo se
2. public abstract class Geometria {
dibujan rectngulos y crculos. De la clase Geometra derivan
las clases Rectangulo y Circulo. Estas clases tienen en comn 3. // clase abstracta que no tiene objetos
ser geometras y como tales tendrn caractersticas comunes
4. public abstract double perimetro();
como permetro y rea. A considerar es que no va a haber
nunca objetos de la clase Geometria. Una clase de la que no 5. public abstract double area();
existen objetos se denomina abstracta, y como tal puede ser
declarada. El fichero Geometria.java define dicha clase. 6. }

La clase Geometria se declara public para permitir que sea usada por otras clases, y como abstract para
indicar que no se permite crear objetos de la misma. Geometria no define variables miembro; s declara 2
mtodos: permetro y area como public (para poder ser usados por otras clases) y abstract para indicar que
no se implementan aqu. La diferencia entre declaracin (primera lnea o header del mtodo) y definicin (la
implementacin, el cdigo). Se indica tambin que su valor de retorno es de tipo double y que no tienen
argumentos (obtendrn sus datos del objeto que se pase como argumento). Es lgico que no se definan en
esta clase los mtodos perimetro y rea, ya que su clculo difiere para un rectngulo y un crculo, y por
tanto estos mtodos habr que definirlos en las clases Rectangulo y Circulo. En la clase Geometria lo que
se indica es cmo sern dichos mtodos: su nombre, nmero y tipo de argumentos y el tipo de retorno.
La clase Rectangulo deriva de 1. // fichero Rectangulo.java
Geometria. Esto se indica en la
2. public class Rectangulo extends Geometria {
sentencia 2 con la palabra
extends. 3. // definicin de variables miembro de la claes
Define 5 variables miembro. En la 4. private static int numRectangulos = 0;
sentencia 4 se define una
5. protected double x1, y1, x2, y2;
variable miembro static. Estas
variables se caracterizan por ser 6. // constructores de la clase
propias de la clase y no de cada
objeto. As, numRectangulos 7. public Rectangulo(double p1x, double p1y, double p2x, double p2y) {
pretende llevar cuenta el nmero 8. x1 = p1x;

Programacin en Java 8
de objetos de esta clase creados.
9. x2 = p2x;
No tiene sentido que cada objeto
10. y1 = p1y;
tuviera su copia de esta variable,
actualizndola cada vez que se 11. y2 = p2y;
crea o destruye un rectngulo.
12. numRectangulos++;
De la variable numRectangulos,
13. }
que en la sentencia 4 se inicializa
a cero, se mantiene slo una 14. public Rectangulo(){ this(0, 0, 1.0, 1.0); }
copia para toda la clase.
15. // definicin de mtodos
Adems esta variable es privada
(private), lo cual quiere decir que 16. public double perimetro() { return 2.0 * ((x1-x2)+(y1-y2)); }
slo las funciones miembro de 17. public double area() { return (x1-x2)*(y1-y2); }
esta clase tienen permiso para
utilizarla. 18. } // fin de la clase Rectangulo

La sentencia 5 define 4 nuevas variables miembro de tipo double, las coordenadas de 2 vrtices opuestos.
Al declararlas protected se indica que slo esta clase, las clases derivadas y las clases del package tienen
permiso para usarlas.
Las sentencias 7-14 definen los constructores de la clase. Los constructores son mtodosque no retornan
valor (ni siquiera void) y su nombre coincide con el de la clase. Los constructores son ejemplo tpico de
sobrecarga. En este caso hay 2 constructores, el segundo sin parmetros: es el constructor por defecto. Las
sentencias 7-13 definen el constructor general. Este constructor recibe 4 argumentos que asigna a las
variables miembro. La sentencia 12 incrementa en uno el nmero de rectngulos creados. La sentencia 14
define un segundo constructor que crea un rectngulo cuando no se dan datos, de lado unidad cuyo primer
vrtice es el origen de coordenadas. Este constructor en realidad no tiene cdigo para inicializar las
variables miembro; llama al constructor general previo con la palabra this.
Las sentencias 16 y 17 contienen la definicin de 1. // fichero Circulo.java
los mtodos miembro perimetro y area. El nombre
2. public class Circulo extends Geometria {
coincide con los de la clase Geometra, pero
seguido del cuerpo del mtodo entre llaves. 3. static int numCirculos = 0;
La clase Circulo deriva de Geometria. Es similar a 4. public static final double PI=3.1415926535897932;
la clase Rectangulo. Se presenta en el cuadro.
5. public double x, y, r;
La sentencia 3 define una variable static o de clase
no definida como private. Si no se especifican 6. public Circulo(double x, double y, double r) {
permisos (public, private o protected) se supone la 7. this.x=x; this.y=y; this.r=r;
opcin por defecto, package, con la que la variable
o mtodo slo puede ser usado por clases del 8. numCirculos++;
package. En el ejemplo no se ha definido ningn 9. }
package; se usa por defecto, el directorio donde se
definen las clases. As, numCirculos podr ser 10. public Circulo(double r) { this(0.0, 0.0, r); }
usada slo por clases del directorio de Circulo. 11. public Circulo(Circulo c) { this(c.x, c.y, c.r); }
La sentencia 4 define una variable static, con la 12. public Circulo() { this(0.0, 0.0, 1.0); }
palabra final, o sea, una constante. Es lgico
definir el nmero como constante y como static 13. public double perimetro() { return 2.0 * PI * r; }
de la clase Circulo, para compartirla. 14. public double area() { return PI * r * r; }
La sentencia 5 (public double x, y, r;) define las 15. // mtodo de objeto para comparar crculos
variables miembro del objeto, las coordenadas del
centro y el radio del crculo. 16. public Circulo elMayor(Circulo c) {

La sentencia 6-9 define el constructor general de la 17. if (this.r>=c.r) return this; else return c;
clase Circulo. En este caso el nombre de los 18. }
parmetros (x, y, r) coincide con el de las variables
miembro. Esto es un problema, porque los 19. // mtodo de clase para comparar crculos
parmetros son variables locales al bloque del 20. public static Circulo elMayor(Circulo c, Circulo d) {
mtodo, destruidas al salir; ocultan variables de
mbito ms general de mismo nombre. Si en el 21. if (c.r>=d.r) return c; else return d;
cdigo del constructor se usan las variables (x, y, r) 22. }
se refieren a los parmetros del mtodo, no a las
variables miembro, las que se desea modificar. 23. } // fin de la clase Circulo

Programacin en Java 9
La sentencia 7 indica cmo se resuelve el problema. Para cualquier mtodo no static de una clase, la
palabra this es una referencia al objeto (argumento implcito) sobre el que se se aplica el mtodo. As, this.x
se refiere a la variable miembro, y x al parmetro del constructor.
Las sentencias 10-12 son otros 3 constructores (sobrecargados), que se diferencian en el nmero y tipo de
parmetros. Los 3 tienen en comn llamar al constructor general, al que se hace referencia con la palabra
this. Al constructor de la sentencia 10 slo se le pasa el radio, con lo cual construye un crculo con ese radio
centrado en el origen de coordenadas. Al constructor de la sentencia 11 se le pasa otro objeto crculo, del
que se hace copia. El de la sentencia 12 es un constructor por defecto, al que no se pasa parmetros y crea
un crculo de radio unidad centrado en el origen. Las sentencias 13 y 14 definen los mtodos perimetro y
area, declarados como abstract en Geometria, adaptados a crculos.
Las sentencias 16-18 definen elMayor, como mtodo de objeto para comparar crculos. Uno de los crculos
es parmetro implcito y el otro explcito. La sentencia 17 muestra cmo al radio del parmetro implcito se
accede en la forma this.r y al del explcito como c.r, donde c es el nombre del objeto pasado como
argumento. La sentencia return devuelve una referencia al objeto cuyo radio sea mayor. Cuando ste es el
argumento implcito se devuelve this.
Las sentencias 20-22 definen elMayor, como mtodo de clase (con static) y por tanto no tiene parmetro
implcito. Los dos objetos a comparar se deben pasar como argumentos explcitos. En ambos casos lo que
se devuelve como retorno no es el objeto de mayor radio, sino una referencia.
Interface Dibujable. El diagrama de clases de la figura 1. // fichero Dibujable.java
indica que las clases RectanguloGrafico y CirculoGrafico
2. import java.awt.Graphics;
son el resultado, tanto de las clases Rectangulo y Circulo
de las que derivan, como de la interface Dibujable. El 3. public interface Dibujable {
concepto de interface es importante en Java.
4. public void setPosicion(double x, double y);
A diferencia de C++, Java no permite herencia mltiple, o
sea, que una clase derive de clases distintas heredando de 5. public void dibujar(Graphics dw);
ambas mtodos y variables miembro. 6. }
La herencia mltiple es fuente de problemas, pero en ocasiones conveniente. Las interfaces de Java son
una alternativa a la herencia mltiple con ventajas prcticas y de estilo. Un interface es un conjunto de
declaraciones de mtodos sin implementacin. Se declara el tipo del valor de retorno y nombre del mtodo,
seguido del tipo de parmetros entre parntesis. Si una clase implementa un interface, se compromete a dar
definicin a los mtodos del interface. En cierta forma un interface es una clase abstract de mtodos
abstract. Una ventaja de los interfaces Java es establecer pautas o modos de funcionamiento similares para
clases que pueden estar o no relacionadas con herencia. Todas las clases que implementan un interface
soportan los mtodos declarados en ella y en este sentido se comportan de modo similar. Las interfaces
pueden relacionarse con herencia, con ms flexibilidad que las clases.
El fichero Dibujable.java define el interface Dibujable para incorporar, en las clases que la implementen, la
capacidad de dibujar sus objetos. El listado muestra la declaracin de los mtodos setPosicion y dibujar. La
declaracin de estos mtodos no tiene nada particular. Como el mtodo dibujar usa como argumento un
objeto de la clase Graphics, hay que importar la clase. Si las clases RectanguloGrafico y CirculoGrafico
implementan el interface Dibujable sus objetos podrn ser mostrados en pantalla.
La clase RectanguloGrafico. 1. // Fichero RectanguloGrafico.java
Deriva de Rectangulo (hereda
2. import java.awt.Graphics;
mtodos y variables miembro) e
implementa la interface Dibujable 3. import java.awt.Color;
(debe definir los mtodos
declarados en el interface). El 4. class RectanguloGrafico extends Rectangulo implements Dibujable {
cuadro muestra la definicin de la 5. // nueva variable miembro
clase.
6. Color color;
Las sentencias 2 y 3 importan
dos clases del package java.awt. 7. // constructor
Podran importarse todas las 8. public RectanguloGrafico(double x1,double y1, double x2, double y2,
clases del package con import
java.awt.*;. 9. Color unColor) {

La sentencia 4 indica que 10. // llamada al constructor de Rectangulo


RectanguloGrafico deriva de la 11. super(x1, y1, x2, y2);
clase Rectangulo e implementa la
interface Dibujable. Se pueden 12. this.color = unColor; // en este caso this es opcional

Programacin en Java 10
implementar varias interfaces, en
13. }
cuyo caso se ponen en el
encabezamiento de la clase 14. // mtodos de la interface Dibujable
separadas por comas.
15. public void dibujar(Graphics dw) {
La sentencia 6 define una nueva
16. dw.setColor(color);
variable miembro que se suma a
las que se tienen por herencia. 17. dw.drawRect((int)x1, (int)y1, (int)(x2-x1), (int)(y2-y1));
Esta nueva variable es un objeto
de la clase Color. 18. }

Las sentencias 8-13 definen el 19. public void setPosicion(double x, double y) {


constructor general de la clase, al 20. ; // mtodo vaco, pero necesario de definir
que llegan los 5 argumentos
para dar valor a las variables 21. }
miembro. 22. } // fin de la clase RectanguloGrafico
En este caso los nombres de los parmetros coinciden con los de las variables miembro, pero slo se usan
para pasrselos al constructor de la superclase. La sentencia 11 contiene la novedad que para dar valor a
las variables heredadas se llama al constructor de la clase padre o superclase con la palabra super.
Las sentencias 14-18 y 19-21 definen // fichero CirculoGrafico.java
los 2 mtodos declarados en el
import java.awt.Graphics;
interface Dibujable. El mtodo dibujar
recibe de parmetro un objeto dw de import java.awt.Color;
la clase Graphics que define el
public class CirculoGrafico extends Circulo implements Dibujable {
contexto de operacin en un panel,
(color de lneas, del fondo, etc.). // se heredan las variables y mtodos de la clase Circulo
La sentencia 16 hace uso de un Color color;
mtodo de la clase Graphics para
determinar el color con que se // constructor
dibujar a partir de ese momento. public CirculoGrafico(double x, double y, double r, Color unColor) {
La sentencia 17 llama a otro mtodo // llamada al constructor de Circulo
de esa misma clase que dibuja un
rectngulo a partir de las coordenadas super(x, y, r);
del vrtice superior izquierdo y de la this.color = unColor;
anchura y altura.
}
Java obliga a implementar o definir
siempre los mtodos declarados por el // mtodos de la interface Dibujable
interface, aunque no se usen. public void dibujar(Graphics dw) {
Por eso, las sentencias 19-21 definen dw.setColor(color);
un mtodo vaco, que slo contiene un
carcter ;. Como no se usa no hay dw.drawOval((int)(x-r),(int)(y-r),(int)(2*r),(int)(2*r));
conflicto, pero hay que implementarlo }
por obligacin de Java.
public void setPosicion(double x, double y) {
La clase CirculoGrafico. Deriva de la
clase Circulo e implementa la interface ;
Dibujable. Es similar a la clase }
RectanguloGrafico como se muestra
en el cdigo del cuadro. } // fin de la clase CirculoGrafico

La clase PanelDibujo. Es responsable final de que los rectngulos y crculos se dibujen en pantalla. Deriva
de la clase Panel, que deriva de Container, que deriva de Component, que deriva de Object. La clase
Component comprende los objetos Java con representacin grfica como botones, barras de
desplazamiento, etc. Los objetos de la clase Container son objetos grficos del AWT capaces de contener
otros objetos del AWT (Abstract Windows Toolkit; biblioteca Java que permite crear GUI).
La clase Panel define los Container ms sencillos, capaces de contener otros elementos grficos (como
otros paneles) y sobre la que dibujar. La clase PanelDibujo contiene el cdigo mostrado a continuacin.
Las sentencias 2-4 importan las clases necesarias para 1. // fichero PanelDibujo.java
construir la clase PanelDibujo. Se importan todas las clases
2. import java.awt.*;
del package java.awt. La clase ArrayList y el interface

Programacin en Java 11
Iterator pertenecen al package java.util, y sirven para tratar
3. import java.util.ArrayList;
colecciones (en este caso conjuntos) de figuras dibujables.
4. import java.util.Iterator;
La sentencia 5 indica que la clase PanelDibujo deriva de la
Panel, heredando de sta y de sus superclases Container y 5. public class PanelDibujo extends Panel {
Component todas sus capacidades grficas.
6. // variable miembro
La sentencia 7 crea una variable miembro v, referencia a un
7. private ArrayList v;
objeto de la clase ArrayList (no es un objeto, es una
referencia o nombre de objeto). 8. // constructor
Las sentencias 9-12 definen el constructor de la clase, que 9. public PanelDibujo(ArrayList va) {
recibe de parmetro la referencia va a un objeto de la clase
ArrayList. En la lista se almacenarn las referencias a los 10. super(new FlowLayout());
objetos (rectngulos y crculos a dibujar). 11. this.v = va;
En la sentencia 10 se llama al constructor de la superclase 12. }
panel, pasndole como argumento un objeto creado de la
clase FlowLayout, que se ocupa de distribuir de determinada 13. // redefinicin del mtodo paint()
forma (de izqda. a dcha. y de arriba abajo) los componentes 14. public void paint(Graphics g) {
grficos que se aaden a un container tal como la clase
Panel. En este caso no tiene mucha importancia, pero 15. Dibujable dib;
conviene utilizarlo. 16. Iterator it;
Un aspecto importante de Java y de la POO es el 17. it = v.iterator();
polimorfismo. Es la propiedad por la que una referencia a un
objeto de una clase puede referirse a objetos de cualquiera 18. while(it.hasNext()) {
de sus clases derivadas. Por ejemplo, es posible en Java 19. dib = (Dibujable)it.next();
hacer lo siguiente:
20. dib.dibujar(g);
Geometria geom1, geom2;
21. }
geom1 = new RectanguloGrafico(0, 0, 200, 100, Color.red);
22. }
geom2 = new CirculoGrafico(200, 200, 100, Color.blue);
23. } // Fin de la clase PanelDibujo
Se crean 2 referencias de la clase Geometria que apuntan a objetos de clases derivadas RectanguloGrafico
y CirculoGrafico. Sin embargo, hay limitacin con las referencias geom1 y geom2. Por ser referencias a la
clase Geometria slo se pueden usar las capacidades definidas en dicha clase, que se reducen al uso de
los mtodos perimetro y area. De la misma forma que con Geometria, es posible usar una referencia del tipo
correspondiente a un interface para manejar objetos de clases que implementan el interface. Por ejemplo:
Dibujable dib1, dib2;
dib1 = new RectanguloGrafico(0,0,200,100,Color.red); dib2 = new CirculoGrafico(200, 200, 100, Color.blue);
donde los objetos referidos por dib1 y dib2 pertenecen a las clases RectanguloGrafico y CirculoGrafico, que
implementan la interface Dibujable. Estos objetos tienen una limitacin: slo pueden ser usados con los
mtodos definidos en el interface Dibujable. Poder usar nombres de una superclase o de un interface
permite tratar de modo unificado objetos distintos, aunque pertenecientes a subclases diferentes o a clases
que implementan el interface. Esta es la idea central del polimorfismo. As, en el cdigo de la clase
PanelDibujo, en las sentencias 14-22 se define el mtodo paint, heredado de Container, que a su vez
redefine el mtodo heredado de Component. En PanelDibujo se redefine el mtodo. El mtodo paint, por lo
general, no lo llama el programador, sino Java y el SO. El programador prepara por una parte la ventana y
el panel en que va a dibujar, y por otra programa en el mtodo paint las operaciones a realizar. El SO y Java
llaman a paint cada vez que entienden que la ventana debe ser dibujada o redibujada. El nico parmetro
de paint es un objeto g de la clase Graphics que constituye el contexto grfico (color de lneas, tipo de letra,
etc.) con el que se realizarn las operaciones.
La sentencia 15 crea una referencia de la clase Dibujable que podr apuntar o contener objetos de cualquier
clase que implemente el interface. La sentencia 16 crea una referencia a un objeto de la interface Iterator
definida en el package java.util, que proporciona los mtodos hasNext, que chequea si la coleccin de
elementos que se est recorriendo tiene ms elementos y next, que devuelve el siguiente elemento de la
coleccin. Cualquier coleccin de elementos (como ArrayList u otra lista vinculada definida por el usuario)
puede implementar este interface y ser usada de modo uniforme.
En la sentencia 17 se usa el mtodo iterator de la clase ArrayList que devuelve una referencia Iterator de los
elementos de la lista v. Obsrvese la diferencia entre el mtodo iterator de la clase ArrayList y el interface
Iterator. En Java los nombres de las clases e interfaces siempre empiezan por mayscula, mientras que los
Programacin en Java 12
mtodos con minscula. Las sentencias 18-21 representan un bucle while cuyas sentencias se repetirn
mientras haya elementos en la enumeracin e (o en el vector v).
La sentencia 19 contiene elementos nuevos. El mtodo it.next devuelve el siguiente objeto de la lista de la
referencia de tipo Iterator. En principio este objeto podra ser de cualquier clase. Los elementos de la clase
ArrayList son referencias de la clase Object, lo que indica que esas referencias pueden apuntar a objetos de
cualquier clase. El nombre de la interface Dibujable entre parntesis representa un cast o conversin entre
tipos diferentes. En Java como en C++, la conversin entre variables u objetos de distintas clases es
importante. Por ejemplo, (int)3.14 convierte el nmero double 3.14 en el entero 3.
No todas las conversiones son posibles, pero s lo son las dadas entre clases de la misma lnea jerrquica
o que implementen el mismo interface. Lo que se indica a la referencia dib con el cast a la interface
Dibujable en la sentencia 19, es que el objeto de la enumeracin va a ser tratado exclusivamente con los
mtodos del interface.
En la sentencia 20 se aplica el mtodo dibujar al objeto referenciado por dib, que forma parte del iterator it,
obtenido a partir de la lista v. Esto es tpico de Java y de la POO. La ventaja del mtodo paint as
programado es que es general: no se hace referencia a las clases RectanguloGrafico y CirculoGrafico,
cuyos objetos son realmente los que se dibujan. Esto permite aadir nuevas clases tales como
TrianguloGrafico, PoligonoGrafico, LineaGrafica, etc., sin modificar el cdigo: tan slo deben implementar el
interface Dibujable. Esta es una ventaja para crear programas extensibles, flexibles y reutilizables.
La clase VentanaCerrable. Es 1. // Fichero VentanaCerrable.java
una clase de utilidad que
2. import java.awt.*;
mejora las caractersticas de la
clase Frame de Java, de la que 3. import java.awt.event.*;
deriva. La clase Frame estndar
4. class VentanaCerrable extends Frame implements WindowListener {
tiene una limitacin: no responde
a las acciones normales en WS 5. // constructores
para cerrar una ventana o
aplicacin, como hacer clic en la 6. public VentanaCerrable() {
X de la esquina superior derecha. 7. super();
En ese caso, para cerrar la 8. }
aplicacin hay que recurrir p. ej.
al comando End Task del Task 9. public VentanaCerrable(String title) {
Manager de WS. Para evitarlo se 10. super(title);
crea la clase VentanaCerrable,
derivada de Frame e implementa 11. setSize(500,500);
la interface WindowListener, 12. addWindowListener(this);
como muestra el cdigo ejemplo.
13. }
VentanaCerrable contiene 2
constructores. El primero por 14. // mtodos de la interface WindowsListener
defecto (sin argumentos) que se 15. public void windowActivated(WindowEvent e) {;}
limita a llamar al constructor de la
superclase Frame con super. 16. public void windowClosed(WindowEvent e) {;}
El segundo constructor admite un 17. public void windowClosing(WindowEvent e) {System.exit(0);}
argumento para poner ttulo a la 18. public void windowDeactivated(WindowEvent e) {;}
ventana. Llama tambin al
constructor de Frame pasndole 19. public void windowDeiconified(WindowEvent e) {;}
este mismo argumento y 20. public void windowIconified(WindowEvent e) {;}
establece un tamao para la
ventana creada (el tamao por 21. public void windowOpened(WindowEvent e) {;}
defecto para Frame es cero). 22. } // fin de la clase VentanaCerrable
La sentencia 12 muestra cmo el AWT de Java gestiona los eventos sobre ventanas y en general sobre la
GUI. Cuando un elemento grfico (aqu la ventana) puede recibir eventos del usuario es necesario indicar
quin se va a encargar de procesarlos. De ordinario al producirse un evento se debe activar un mtodo que
se encargue de procesarlo y realizar acciones (en este caso cerrar la ventana y la aplicacin). La sentencia
12 ejecuta el mtodo addWindowListener de la clase Frame (que a su vez heredado de la clase Window).
El parmetro que se pasa al mtodo indica qu objeto gestiona los eventos de la ventana implementando la
interface WindowListener. En este caso, como el parmetro es this, la propia clase VentanaCerrable
gestiona los eventos. Como el constructor por defecto de las sentencias 6-8 no usa el mtodo

Programacin en Java 13
addWindowListener(), si se construye una VentanaCerrable sin ttulo no podr ser cerrada del modo
habitual. As se ha hecho en este ejemplo para poder comprobarlo.
El interface WindowListener define los 7 mtodos para gestionar los eventos con los que actuar sobre una
ventana. Para cerrar la ventana slo es necesario definir el mtodo windowClosing(). Sin embargo,
implementar un interface obliga a definir todos sus mtodos. Por ello en las sentencias 15-21 los mtodos
estn vacos, excepto el que interesa, que llama al mtodo exit de System. El argumento 0 indica
terminacin normal del programa.
1.2. Nomenclatura y estructura de un programa Java
Los nombres de Java son sensibles a maysculas y minsculas (case-sensitive). Es habitual seguir ciertas
normas de estilo que facilitan la lectura y mantenimiento del cdigo. Algunas son:
1. Es habitual usar nombres en minsculas, con las excepciones siguientes
2. Cuando un nombre consta de varias palabras se escriben seguidas con mayscula la primera letra de
cada palabra (elMayor, VentanaCerrable, RectanguloGrafico)
3. Los nombres de clases e interfaces comienzan siempre por mayscula (Geometria, Rectangulo)
4. Los nombres de objetos, mtodos y variables miembro, y los de las variables locales de los mtodos,
comienzan siempre por minscula (main, dibujar, numRectangulos)
5. Los nombres de variables finales (constantes) siempre con maysculas (PI, TAM)
El anterior ejemplo presenta la estructura habitual de un programa codificado en un lenguaje de POO.
Primero, una clase con el programa principal (con la funcin main y clases de usuario) usadas por el
programa principal. Los ficheros fuente tienen extensin *.java, y los compilados extensin *.class. Un
fichero fuente puede contener ms de una clase, pero slo una puede ser public. El nombre del fichero
fuente debe coincidir con el de la clase public, considerando el case-sensitive. Si la clase no es public, no es
necesario que su nombre coincida con el del fichero. Una clase puede ser public o package (default).
En general, una aplicacin est formada por varios ficheros *.class. Cada clase realiza unas funciones
permitiendo construir aplicaciones con independencia entre clases. La aplicacin se ejecuta con el nombre
de la clase que contiene la funcin main. Las clases se agrupan en packages; bibliotecas. Si las clases no
se definen pertenecientes a un package, se usa un package por defecto (default): el directorio de trabajo.
Clase. Una clase es una agrupacin de datos y mtodos que los manejan: las variables y mtodos miembro.
La POO se basa en la programacin de clases. Un programa se construye a partir de un conjunto de clases.
Objeto. Son elementos particulares de una clase. Cada objeto posee sus propias variables miembro, con
valores particulares distintos de los valores del resto de objetos de la clase. Las clases pueden tener
variables static, que son propias de la clase y no de cada objeto.
Herencia. Es la propiedad que permite definir nuevas clases basadas en clases existentes, reutilizando el
cdigo. Si una clase deriva de otra (extends) hereda sus variables y mtodos. La clase derivada puede
aadir nuevas variables y mtodos y/o redefinir los heredados. En Java una clase slo puede derivar de una
sla clase: no permite herencia mltiple en base a clases. Sin embargo es posible simular la herencia
mltiple con interfaces.
Interface. Es un conjunto de declaraciones de funciones. Si una clase implementa (implements) un interface,
debe definir todas las funciones especificadas por el interface. Una clase puede implementar ms de un
interface, simulando as herencia mltiple. A su vez, un interface puede derivar de una o varias interfaces,
en cuyo caso incorpora todos los mtodos de las interfaces de las que deriva.
Package. Es una agrupacin de clases. Una biblioteca. Existen packages estndar del lenguaje y el usuario
puede crear sus propios packages. Lo habitual es reunir en packages clases relacionadas. Todas las clases
que formen parte de un package deben estar en el mismo directorio.
Jerarqua de clases Java (API). La documentacin on-line del API de Java muestra la jerarqua de clases
(relaciones de herencia) e informacin de los packages de las bibliotecas base de Java. La diferencia es
que el package es una agrupacin arbitraria de clases. La jerarqua marca la herencia entre clases.
En la documentacin on-line se presenta Package Index y Class Hierarchy. El primero presenta la
estructura del API de Java por packages; el segundo la jerarqua de clases. Si se selecciona una clase se
muestra una descripcin de los mtodos y variables de la clase. A su vez muestra su herencia completa.

Programacin en Java 14
2. PROGRAMACIN EN JAVA
Java como lenguaje de programacin algortmico es simila a otros como C/C++, en los que se inspira.
2.1. Tipos y nombres de variables. Tipos Primitivos
Una variable es un nombre que identifica un valor que puede cambiar. Segn el tipo de dato que contenga,
en Java hay 2 tipos principales de variables:
Variables de tipos primitivos. Se definen con un tipo de valor nico que puede ser entero, de punto flotante,
carcter o booleano. Java permite distinta precicin y rangos para estos tipos (char, byte, short, int, long,
float, double, boolean).
Variables referencia. Son referencias o nombres de datos ms complejos: arrays u objetos de una clase.
Desde el punto de vista del mbito del programa, las variables pueden ser:
Variables miembro. Se definen en una clase, fuera de mtodos; pueden ser tipos primitivos o referencias.
Variables locales. Se definen en un mtodo o en un bloque entre llaves. Se crean en el interior del bloque y
se destruyen al finalizar dicho bloque. Pueden ser tipos primitivos o referencias.
Un nombre de variable en Java se puede crear con libertad. Puede ser cualquier conjunto de caracteres
numricos y alfanumricos, sin algunos caracteres especiales como operadores o separadores ( ,.+-*/ etc.).
En Java existen palabras reservadas, que no se pueden usar como nombres de variables. Son:
Palabras Reservadas JAVA
abstract boolean break byte case catch char class
const* continue default do double else extends final
finally float for goto* if implements import instanceof
int interface long native new null package private
protected public return short static super switch synchronized
this throw Throws transient try void volatile while
(*) son palabras reservadas, pero no se utilizan en la actual implementacin del lenguaje Java
Los tipos primitivos de variables Java son variables sencillas con tipos de datos simples como valores
boolean, enteros, etc. Java dispone 8 tipos primitivos de datos. Boolean almacena valores true y false; char
almacena caracteres y 6 tipos para valores numricos, 4 tipos para enteros (byte, short, int y long) y 2 para
reales de punto flotante (float y double). Los rangos y memoria que ocupa cada uno se muestra en la tabla:
Tipo de variable Descripcin
Boolean 1 B. Valores true y false
Char 2 B. Unicode. Comprende el cdigo ASCII
Byte 1 B. Valor entero entre -128 y 127
Short 2 B. Valor entero entre -32768 y 32767
Int 4 B. Valor entero entre -2.147.483.648 y 2.147.483.647
Long 8 B. Valor entre -9.223.372.036.854.775.808 y 9.223.372.036.854.775.807
Float 4 B (entre 6 y 7 cifras decimales equivalentes). De -3.402823E38 a -1.401298E-45 y
de 1.401298E-45 a 3.402823E38
Double 8 bytes (~ 15 cifras decimales equivalentes). De -1.79769313486232E308 a -
4.94065645841247E-324 y de 4.94065645841247E-324 a 1.79769313486232E308
El tipo boolean no es numrico; no se identifica con igual o distinto de cero, como en C/C++. El resultado de
una expresin lgica es boolean. El tipo char se codifica en UNICODE (incluye ASCII y son 16 bits / car).
Los tipos byte, short, int y long son nmeros enteros con rangos distintos. A diferencia de C/C++, en Java
no hay enteros unsigned. Los tipos float y double son valores de punto flotante (nmeros reales) con 6-7 y
15 cifras decimales equivalentes, respectivamente. Se usa la palabra void para indicar ausencia de un tipo
de dato en una variable. A diferencia de C/C++, los tipos de variables en Java estn perfectamente
definidos en todas las plataformas. Extensiones de Java 1.2 aprovechan la arquitectura Intel, permitiendo
operaciones de punto flotante con precisin extendida de 80 bits.

Programacin en Java 15
2.1.1. Definicin, inicializacin, visibilidad y vida
Una variable se define especificando tipo y nombre. Pueden ser de tipos primitivos o referencias a objetos
de alguna clase de la API Java o generada por usuario. Si no se especifica un valor en su declaracin, las
variables primitivas se inicializan a cero (salvo boolean y char, que se inicializan a false y '\0'). Las variables
de tipo referencia se inicializan por defecto al valor null.
Es importante distinguir entre la referencia a un objeto y el objeto. Una referencia es una variable que indica
dnde est guardado un objeto en memoria (a diferencia de C/C++, Java no permite acceder al valor de la
direccin, ya que no usa punteros). Al declarar una referencia no se apunta nada, por eso se asigna a null.
Si se desea que esa referencia apunte a un objeto hay que crearlo con el operador new, que reserva en
memoria espacio para ese objeto (variables y mtodos). Tambin se puede igualar la referencia a otra
referencia de un objeto existente.
Un tipo particular de referencias son los arrays o vectores, de variables primitivas u objetos. En la
declaracin de una referencia tipo array hay que incluir corchetes. Java garantiza que los elementos del
vector son inicializados a null o a cero (segn tipo de dato) en caso de no indicar valor. En los ejemplos
aparece cmo crear un vector de 10 nmeros enteros y cmo crear uno de elementos MyClass:
int x; // Declaracin de la variable primitiva x. Se inicializa a 0
int y = 5; // Declaracin de la variable primitiva y. Se inicializa a 5
MyClass unaRef; // Declaracin de una referencia a un objeto MyClass. Se inicializa a null
unaRef = new MyClass(); // La referencia apunta al objeto creado con el constructor por defecto
MyClass segundaRef = unaRef; // Declaracin referencia a objeto MyClass. Se inicializa al valor de unaRef
int [] vector; // Declaracin de un array. Se inicializa a null
vector = new int[10]; // Vector de 10 enteros, inicializados a 0
double [] v = {1.0, 2.65, 3.1}; // Declaracin e inicializacin de vector de 3 elementos
MyClass [] lista=new MyClass[5]; // Se crea un vector de 5 referencias a objetos inicializadas a null
lista[0] = unaRef; // Se asigna a lista[0] el mismo valor que unaRef
lista[1] = new MyClass(); // Se asigna a lista[1] la referencia al nuevo objeto. lista[2] siguen a null
En el ejemplo las referencias unaRef, segundaRef y lista[0] actuarn sobre el mismo objeto. Es equivalente
usar cualquiera de las referencias ya que el objeto al que se refieren es el mismo.
Se entiende por visibilidad, mbito o scope de una variable, la parte de la aplicacin donde es accesible y
por tanto puede ser usada. En Java todas las variables deben estar incluidas en una clase.
En general las variables declaradas entre llaves, es decir en un bloque, son visibles y existen en ese bloque.
Por ejemplo las variables declaradas al principio de una funcin existen mientras se ejecute la funcin; las
variables declaradas en un bloque if no sern vlidas al finalizar las sentencias del if y las variables miembro
de una clase son vlidas mientras existe el objeto de la clase.
Las variables miembro de una clase declaradas public son accesibles con una referencia a un objeto de
dicha clase usando el operador punto.
Las variables miembro de una clase declaradas private no son accesibles directamente desde otras clases.
Los mtodos miembro de una clase tienen acceso a todas las variables miembro de la clase sin necesidad
de anteponer el nombre de un objeto. Pero los mtodos miembro de una clase B derivada de otra A, tienen
acceso a todas las variables miembro de A declaradas como public o protected, pero no a las private.
Una clase derivada slo puede acceder directamente a las variables y mtodos miembro public o protected
de su clase base. Otra caracterstica es que es posible declarar una variable en un bloque con el mismo
nombre que una variable miembro, pero no con el nombre de otra variable local existente. La variable
declarada en el bloque oculta a la variable miembro. Para acceder a la variable miembro oculta ser preciso
usar el operador this, en la forma this.varname.
Un aspecto importantes en la POO es la forma en que se crean y eliminan objetos. En Java la forma de
crear nuevos objetos es usar el operador new. Al usar new, la variable de tipo referencia guarda la posicin
de memoria donde se almacena ese objeto. Para cada objeto se lleva cuenta de las variables que lo
apuntan. La eliminacin de los objetos la realiza el programa Garbage Collector, que automticamente
libera la memoria asignada a un objeto cuando no existe ninguna referencia que lo apunte. Esto es, que
aunque una variable de tipo referencia deje de existir, el objeto al quel apunta no es eliminado si hay otras
referencias apuntando a ese objeto.

Programacin en Java 16
2.1.2. Clases BigInteger y BigDecimal
Java 1.1 incorpor 2 nuevas clases destinadas a operaciones aritmticas que requieran gran precisin:
BigInteger y BigDecimal. La forma de operar con objetos de estas clases difiere de las operaciones con
variables primitivas. En este caso hay que realizar las operaciones con mtodos propios de estas clases
(add para sumar, subtract, etc.). Se puede consultar la ayuda del package java.math, donde aparecen
ambas clases con todos sus mtodos. Los objetos tipo BigInteger almacenan cualquier nmero entero sin
perder informacin durante las operaciones. Anlogamente los objetos de tipo BigDecimal permiten trabajar
con el nmero de decimales deseado.
2.2. Operadores y precedencia
Java es un lenguaje rico en operadores. La tabla muestra los tpicos.
Operadores Lxico Sintaxis Semntica
Aritmticos +, -, *, /, % op1 [operador] op2 Operaciones aritmticas habituales
= [variable] = [expresin] Asignar un valor a una variable
De asignacin +=, -=, op1 [operador] op2 op1 = op1 [operador] op2
*=, /=, %=
Relacionales ==, >, < op1 [operador] op2 El resultado es true si se cumple que op1
es igual, mayor que op2. En caso
>=, <=, !=
contrario es false
&&, & (AND) op1 [operador] op2 Si se usa &&, si op1 es false no se evala
op2. Si se usa &, op2 se evala siempre.
Lgicos ||, | (OR)
Si se usa ||, si op1 es true, no se evaa
op2. Si se usa |, op2 se evala siempre
! (NOT) ! [expresin] Negacin lgica.
Instanceof instanceof [objeto] instanceof [clase] Indica si un objeto pertenece a una clase
Condicional ?: ?: [expression] ? res1 : res2 Bifurcacin condicional sencilla
Incrementales ++, -- ++[variable], [variable]++ Se incrementa o decrementa la variable
en una unidad
--[variable], [variable]--
Concatenacin + [cadena]+[cadena] Concatena cadenas de caracteres
>>, << op1 [operador] op2 Desplaza los bits de op1 a la derecha
(izquierda) una distancia op2
>>> op1 [operador] op2 Desplaza los bits de op1 a la derecha una
De operacin
distancia op2 (positiva)
de bits
&, |, ^ op1 [operador] op2 Operaciones lgicas AND, OR y XOR
~ ~ op1 Complemento de los bits de op1
De asignacin &=, |=, ^=,
a bits <<=, >>=,
op1 [operador] op2 op1 = op1 [operador] op2
>>>=
Los operadores aritmticos + y aplicados slo a un operando, se denominan unarios y mantienen o
cambian el signo de un valor como en el clculo matemtico habitual.
Los operadores relacionales sirven para realizar comparaciones. El resultado es siempre un valor boolean
(true o false) segn se cumpla o no la relacin expresada.
Los operadores lgicos construyen expresiones lgicas, combinando valores lgicos o resultados de
operaciones relacionales. La semntica puede variar en el caso que se evale o no op2. Por eso se
incluyen los operadores & y | individuales.
El operador condicional ?:, tomado de C/C++ evala una expresin lgica y se devuelve res1 si el resultado
es true y res2 si es false. Es el nico operador ternario (3 argumentos) de Java. Como todo operador que
devuelve un valor puede ser usado en una expresin. Por ejemplo las sentencias: x=1 ; y=10; z =
(x<y)?x+3:y+8; asignaran a z el valor 4 (x+3).

Programacin en Java 17
Los operadores incrementales se aplican en preincremento, si se escriben antes de la variable, de forma
que primero se incrementa el valor y luego se usa o en postincremento, en que primero se usa el valor de la
variable y luego se incrementa (o decrementa). Su uso en contadores de bucles es muy frecuente.
Los operadores que actan a nivel de bit, se postfix operators [] . (params) expr++ expr--
suelen usar para definir banderas o flags; variables
unary operators ++expr --expr +expr -expr ~ !
enteras en las que cada bit posee un significado.
En binario, las potencias de dos se representan creation or cast new (type)expr
con un nico bit activado. P. ej., los nmeros (1, 2,
4, 8, 16, 32, 64, 128) se representan en binario con multiplicative */%
8 bits como (00000001, 00000010, 00000100, additive +-
00001000,, 10000000).
shift << >> >>>
La suma de estos nmeros permite construir una
variable flags con los bits activados que se deseen. relational < > <= >= instanceof
Por ejemplo, para construir una variable flags equality == !=
00010010 se hara flags=2+16. Para saber si el
segundo bit por la derecha est o no activado se bitwise AND &
usara la sentencia, if (flags & 2 == 2) {...}. bitwise exclusive OR ^
La precedencia de operadores marca el orden en bitwise inclusive OR |
que se realizan las operaciones, lo que condiciona
su resultado. La lista muestra la precedencia de logical AND &&
mayor a menor. En Java, todos los operadores logical OR ||
binarios, excepto los de asignacin, se evalan de
izquierda a derecha. Los de asignacin se evalan conditional ?:
de derecha a izquierda; el valor de la derecha se assignment =, +=, -=,, >>=, >>>=
copia sobre la variable de la izquierda.
2.3. Estructuras de control
Las estructuras de control permiten gestional el orden de ejecucin del proceso. En resumen, bifurcaciones
y bucles. En la mayora de lenguajes son comunes aunque vare su sintaxis. En Java es similar a C/C++.
Una sentencia es una instruccin que acaba en punto y coma. Se permite incluir varias sentencias en una
lnea, aunque lo habitual es usar una lnea por sentencia.
Existen 3 formas de introducir comentarios en cdigo Java, similares a C++. Se usa // para introducir
comentarios en una lnea de cdigo. Un comentario puede empezar al comienzo de la lnea o a
continuacin de una instruccin. Tambin se puede usar /**/, para comentarios de ms de una lnea. En
Java adems se puede usar el smbolo /***/ con algunos caracteres especiales, para generar la
documentacin sobre clases y packages automticamente. Introducidos los comentarios, el programa
javadoc.exe genera automticamente la informacin de forma similar a la de la documentacin del JDK.
2.3.1. Bifurcaciones
Permiten controlar el flujo de ejecucin Bifurcacin if Bifurcacin if-elseif-else
eligiendo una de entre varias acciones en
funcin del valor de una expresin lgica o if (booleanExpression) { if (booleanExpression1) {
relacional. Existen 2 tipos: if y switch. statements; statements1;
If ejecuta un bloque de sentencias segn el } } elseif (booleanExpression2) {
valor de la expresin de control: se ejecuta si
la condicin es cierta. Las llaves agrupan en Bifurcacin if else statements2;
un bloque las sentencias a ejecutar. Si slo if (booleanExpression) { } elseif (booleanExpression3) {
hay una sentencia no se exigen llaves.
statements1; statements3;
La bifurcacin if else es anloga a if; es una
ampliacin. Las sentencias incluidas en el } else { } else {
else se ejecutan en el caso de no cumplirse la statements2; statements4;
expresin de comparacin.
} }
La bifurcacin if-elseif-else permite introducir ms de una expresin de comparacin. Si la primera condicin
no se cumple, se compara la segunda y as sucesivamente. En caso de que no se cumpla ninguna de las
comparaciones elseif, se ejecutan las sentencias del else. Su estructura es la mostrada en la tabla.
La bifurcacin switch es alternativa a if-elseif-else cuando switch (expression) {
se compara la misma expresin con distintos valores. Su
case value 1: statements 1; break;

Programacin en Java 18
forma general es la mostrada. Sus caractersticas ms
case value 2: statements 2; break;
relevantes son las siguientes:

1. Cada sentencia case se corresponde con un nico valor
de expression. No se pueden establecer rangos o case value n: statements n; break;
condiciones; slo valores concretos.
[default: statements m;]
2. Los valores no comprendidos en ninguna sentencia case
}
se pueden gestionar en default, que es opcional.
3. En ausencia de break, cuando se ejecuta una sentencia case se ejecutan tambin las que van a
continuacin, hasta llegar a un break o terminar el switch.
El cuadro muestra 2 ejemplos de uso de las sentencias if y switch.
int numero = 61; // "numero" tiene 2 dgitos char c = (char)(Math.random()*26+'a'); // Generacin
aleatoria de letras minsculas
if(Math.abs(numero) < 10)
System.out.println("Numero tiene 1 digito "); System.out.println("La letra " + c );
else if (Math.abs(numero) < 100) switch (c) {
System.out.println("N de 1 digito ");
case 'a': // Se compara con a
else {
case 'e': // Se compara con e
System.out.println("N de dgitos>3 ");
case 'i': // Se compara con i
System.out.println ("Ejecutada opcion por defecto
case 'o': // Se compara con o
");
case 'u': System.out.println(" Es vocal "); break;
}
default: System.out.println(" Es consonante ");
}
2.3.2. Bucles
Un bucle realiza un proceso repetidas veces. El cdigo incluido entre llaves (opcionales si el proceso consta
de nica lnea) se ejecuta mientras se cumpla su condicin. Por eso, hay que controlar que la condicin se
da al menos una vez para salir del bucle.
2.3.2.1. While y Do while
El bucle while se realiza mientras sus condiciones sean ciertas. La tabla muestra su estructura.
El bucle do while es el mismo, pero el control Bucle while Bucle do while
se hace al final del bucle, por lo que el
bloque se ejecutar al menos una vez, se while (booleanExpression) { do {
cumpla o no la condicin. Este tipo de bucle statements; statements
se usa para controlar la satisfaccin de una
condicin de error o convergencia. } } while (booleanExpression);

2.3.2.2. For
En el cuadro se Bucle For Equivalencia While
presenta la forma
general del bucle for y initialization;
su equivalencia con el for (initialization; booleanExpression; increment) { while (booleanExpression) {
bucle while. La
initializacin se hace al statements; statements;
comienzo del for y el } increment;
incremento despus.
}
La expresin booleana se evala al comienzo de cada iteracin; el bucle termina cuando la expresin de
comparacin no se cumple.
Cualquiera de las tres partes puede estar for(int i = 1, j = i + 10; i < 5; i++, j = 2*i) { i = 1 j = 11
vaca. La initialization y el increment
System.out.println(" i = " + i + " j = " + j); i=2 j=4
pueden tener varias expresiones
separadas por comas. Por ejemplo, el } i=3 j=6
cdigo de la izquierda produce la salida
i=4 j=8
de la derecha.

Programacin en Java 19
2.3.2.3. Break, continue y return
Break es vlido para bifurcaciones y bucles. Evita realizar el resto de sentencia del bloque en ejecucin.
Continue se usa en bucles, no en bifurcaciones. Finaliza la iteracin en ejecucin, evitando el resto de
sentencias hasta el final del bucle y vuelve a la siguiente iteracin (i+1).
Java provee etiquetas para indicar un Bucle1: // etiqueta
lugar donde continuar la ejecucin tras un
for ( int i = 0, j = 0; i < 100; i++){
break o continue. El nico lugar donde se
pueden incluir es delante de un bloque de while ( true ) {
cdigo entre llaves (if, switch, do...while,
if( (++j) > 5) { break bucle1; } // Finaliza ambos bucles
while, for) y slo se usan al disponer uno
o ms bucles (o bloques) en otro bucle y else { break; } // Finaliza el bucle interior (while)
se desea salir o continuar con la
siguiente iteracin (continue) de un bucle }
que no es el actual. }
Por tanto, break [labelName] finaliza el bloque labelName. En el ejemplo, break bucle1 finaliza los 2 bucles
pero break slo termina el while y sigue la ejecucin del for. Ambos bucles finalizan con i=5 y j=6. Continue,
dentro de al menos un bucle, tambin permite transferir el control a un bucle con etiqueta. Por ejemplo, la
sentencia, continue bucle1 pasara a ejecutar el bucle for tras la etiqueta bucle1 para su nueva iteracin.
Otra forma de salir de un bucle (y un mtodo) es con la sentencia return. En caso que la funcin devuelva
alguna variable, el valor se escribe a continuacin de return (return value).
2.3.3. Try, catch, finally
Java incorpora gestin de errores. La deteccin de errores sintcticos se hace en compilacin. El resto se
dan en ejecucin. En Java, una Exception es un tipo de error o condicin anormal producida en ejecucin.
Algunas excepciones son fatales y provocan que se deba finalizar la ejecucin. Caso en que conviene
terminar ordenadamente y dar mensaje de error explicativo. Otras excepciones, como no encontrar un
fichero en el que leer o escribir, pueden ser recuperables. El programa debiera dar al usuario la oportunidad
de corregir el error (definiendo por ejemplo un nuevo path del fichero no encontrado).
Un programador chequea errores con la clase Exception (java.lang.Exception) que deriva de la Throwable.
Java obliga a tener en cuenta ciertas excepciones con bloques try, catch y finally. El cdigo en el bloque try
est controlado. Si se produce una situacin de error y una excepcin, el control pasa al bloque catch, que
se hace cargo de la situacin y decide lo que hacer. Se pueden incluir tantos bloques catch como se desee.
Cada uno trata un tipo de excepcin. Si void metodo1() {
est presente, se ejecuta el bloque
...
finally, que aunque pcional, en caso de
existir se ejecuta siempre. En caso que try { // Cdigo que puede lanzar las excepciones
el cdigo de un mtodo genere una
Exception y no se incluya en l la ...
gestin del error (bucles try/catch) el } catch (IOException e1) { // IOException y da aviso
mtodo debe pasarla al mtodo desde
el que ha sido llamado. System.out.println(e1.getMessage());

Esto se consigue con throws [nombre } catch (MyException e2) { // MyException, avisa y finaliza
de la Exception], despus de la lista de System.out.println(e2.getMessage()); return;
argumentos del mtodo. El mtodo
superior debe incluir los bloques } finally { // Sentencias que se ejecutarn en todo caso
try/catch o volver a pasar la Exception. ...
As se puede pasar la Exception de un
mtodo a otro hasta llegar al ltimo del }]
programa, el main(). ...
En el ejemplo se presentan 2 mtodos } // Fin del metodo1
que controlan una IOException
relacionada con la lectura ficheros y void metodo2() throws IOException, MyException {
una MyException propia. El primero de ...
ellos (metodo1) realiza la gestin de las
excepciones y el segundo (metodo2) // Cdigo que puede lanzar IOException y MyException
las pasa al siguiente mtodo. } // Fin del metodo2

Programacin en Java 20
3. CLASES EN JAVA
Las clases son la esencia de la POO. Los conceptos que maneja la POO son:
Clase. Es un tipo de datos abstracto (TDA) que agrupa datos (variables o campos) y de funciones (mtodos)
que operan sobre esos datos.
Encapsulacin. Las clases pueden ser declaradas como pblicas (public) y como package (accesibles slo
a clases del package). Las variables miembro y los mtodos pueden ser public, private, protected y
package. De esta forma se puede controlar el acceso y evitar un uso inadecuado.
Herencia. Una clase puede derivar de otra (extends), y en ese caso hereda todas sus variables y mtodos.
Una clase derivada puede aadir variables y mtodos y/o redefinir las variables y mtodos heredados.
Polimorfismo. Los objetos de distintas clases pertenecientes a una misma jerarqua o que implementan una
misma interface pueden tratarse de una forma general e individualizada, al mismo tiempo. Esto facilita la
programacin y el mantenimiento del cdigo.
La definicin sigue la sintaxis del cuadro. La palabra public [public] class Classname {
es opcional. Si no se indica la clase adquiere visibilidad por
// definicin de variables y mtodos
defecto: slo para las clases del package. Los mtodos y
variables deben ser definidos en el bloque de la clase. Un ...
objeto (instance) es un ejemplar concreto de una clase. De
}
ah, que clase se asocia a tipo de dato y objeto a variable.
Las clases como TDA (tipos abstractos de datos) son pensadas como un tipo de variable. Por ejemplo, un
tipo entero. Un objeto es pensado como una variable de un tipo de datos, una clase. Caractersticas de las
clases en Java son:
1. Todas las variables y mtodos Java deben pertenecer a una clase. No hay variables y funciones globales
2. Si una clase deriva de otra (extends), hereda todas sus variables y mtodos
3. Java tiene una jerarqua de clases estndar de la // fichero Circulo.java
que pueden derivar las clases que se creen
public class Circulo extends Geometria {
4. Una clase slo puede heredar de una nica clase
static int numCirculos = 0;
(no hay herencia mltiple). Si al definir una clase no
se especifica quin deriva, por defecto se deriva de public static final double PI=3.141592653589;
Object, clase base de la jerarqua de clases Java
public double x, y, r;
5. En un fichero se pueden definir varias clases,
public Circulo(double x, double y, double r) {
pero slo una como public. El fichero, de extensin
*.java se debe llamar como esa clase public. Con this.x=x; this.y=y; this.r=r;
excepciones, lo habitual es escribir una sola clase
por fichero numCirculos++;

6. Si una clase de un fichero no es public, no es }


necesario que el fichero se llame como la clase public Circulo(double r) { this(0.0, 0.0, r); }
7. Los mtodos de una clase pueden ser referidos public Circulo(Circulo c) { this(c.x, c.y, c.r); }
de modo global al objeto de esa clase al que se
aplican con la referencia this 8. Las clases pueden public Circulo() { this(0.0, 0.0, 1.0); }
agruparse en packages con la lnea al comienzo del public double perimetro() { return 2.0 * PI * r; }
fichero package packageName;. La agrupacin en
packages se relaciona con la jerarqua de directorios public double area() { return PI * r * r; }
y ficheros en que se guardan clases // mtodo de objeto para comparar crculos
Otro concepto importante en Java, asociado a la public Circulo elMayor(Circulo c) {
idea de herencia mltiple es el de interface.
if (this.r>=c.r) return this; else return c;
Interface. Es un conjunto de declaraciones de
funciones. Si una clase implementa (implements) un }
interface, debe definir las funciones especificadas en // mtodo de clase para comparar crculos
la interface.
public static Circulo elMayor(Circulo c, Circulo d) {
Las interfaces pueden definir variables finales
(constantes). Una clase puede implementar ms de if (c.r>=d.r) return c; else return d;
un interface: es la alternativa a la herencia mltiple. }
En algunos aspectos los nombres de las interfaces
pueden usarse en lugar de las clases. } // fin de la clase Circulo

Programacin en Java 21
Por ejemplo, las interfaces pueden definir referencias a objetos de cualquier clase que la implemente. Con
ese nombre slo se pueden usar los mtodos de la interface. Es un aspecto importante del polimorfismo.
Una interface puede derivar de otra o de varias, caso en que incorpora las declaraciones de todos los
mtodos de las interfaces de las que deriva. Las interfaces Java, no las clases, s tienen herencia mltiple.
El ejemplo define una clase Circulo y muestra cmo se definen variables miembro y mtodos. Variables y
mtodos pueden ser de objeto o de clase (static). El nombre del fichero coincide con el de la clase public
con la extensin *.java.
3.1. Variables
Un aspecto importante es la inicializacin de datos. Las variables miembro de tipos primitivos se inicializan
automticamente, incluso antes de llamar al constructor (false para boolean, carcter nulo para char y 0
para tipos numricos). Lo suyo es inicializarlas tambin en el constructor.
Variables miembro (de objeto). Cada objeto tiene su copia de las variables miembro de la clase (tambin
llamadas campos) que podrn ser de tipo primitivo (boolean, int) o referencias a objetos de otra clase
(composicin). La clase Circulo tiene sus propias coordenadas del centro x e y, y su propio valor del radio r.
Las variables miembro pueden inicializarse en la declaracin, con constantes o llamadas a mtodos (algo
no permitido en C++). Se inicializan en el orden en que aparecen en el cdigo de la clase. Es importante
porque unas variables pueden apoyarse en otras previas. Por ejemplo, long nDatos = 100;.
Los mtodos de objeto se referencian con el nombre del objeto, punto, nombre del mtodo. A este objeto se
le llama argumento implcito. Para calcular el rea del objeto c1 de la clase Circulo, se escribe: c1.area();.
Las variables miembro del argumento implcito se acceden directamente o con this y el punto.
Las variables miembro pueden precederse en su declaracin por los modificadores de acceso: public,
private, protected y package (valor por defecto que puede omitirse). Junto a los modificadores de acceso de
la clase (public y package), determinan los permisos para usar la clase y sus mtodos y variables miembro.
Existen otros 2 modificadores, no de acceso, para las variables miembro:
Transient. Indica que la variable miembro no forma parte de la persistencia de un objeto (capacidad de
mantener su valor al terminar la ejecucin) y por tanto no debe ser serializada (convertida en flujo de
caracteres para poder almacenarse en disco o en BBDD) con el resto del objeto.
Volatile. Indica que la variable puede ser usada por distintos threads sincronizados y que el compilador no
debe realizar optimizaciones con esa variable.
Variables miembro (de clase o static). Una clase puede tener variables propias, pero no de cada objeto. A
estas variables se les llama de clase o static. Se suelen usar para definir constantes comunes o variables
con sentido para toda la clase. En Java son lo ms parecido a variables globales de C/C++.
Se crean anteponiendo static a su declaracin. Para llamarlas se suele usar el nombre de la clase (no es
imprescindible, pues se puede usar el nombre de cualquier objeto), para aclarar su sentido. P. ej.,
Circulo.numCirculos es una variable de clase que cuenta el nmero de crculos creados. Si no se les da
valor en la declaracin, las variables miembro static se inicializan con los valores por defecto para los tipos
primitivos y con null si es una referencia.
Las variables static se crean en el momento en que pueden ser necesarias: al crear el primer objeto de la
clase, al llamar a un mtodo static o al usar una variable static de dicha clase. Lo importante es que las
variables static se inicializan siempre antes que cualquier objeto de la clase.
Variables finales. Una variable de un tipo primitivo declarada como final no puede cambiar su valor en
ejecucin. Puede ser considerada como una constante equivliendo a la palabra const de C/C++.
Java permite separar definicin e inicializacin de una variable final. La inicializacin puede hacerse en
tiempo de ejecucin, llamando a mtodos o en funcin de otros datos. La variable final as definida es
constante, pero su valor puede variar entre ejecuciones del programa, pues depende de cmo se inicialice.
Adems de las variables miembro, las locales y los argumentos de un mtodo pueden ser declarados final.
Declarar como final un objeto miembro de una clase hace constante la referencia, pero no el objeto, que
puede ser modificado con otra referencia. En Java no es posible hacer que un objeto sea constante.
3.2. Mtodos (funciones miembro)
3.2.1. Mtodos de objeto
Los mtodos son subrutinas definidas en una clase. Salvo los static o de clase, se aplican siempre a un
objeto con el operador punto. El objeto es su argumento implcito. Los mtodos pueden adems tener otros
argumentos explcitos entre parntesis en forma habitual. La primera lnea de la definicin de un mtodo se
llama declaracin o header; el cdigo comprendido entre las llaves {} es el cuerpo del mtodo.

Programacin en Java 22
Sea el mtodo de la clase Circulo mostrado. El header contiene el // header y comienzo del mtodo
cualificador de acceso (public), del tipo del valor de retorno (Circulo;
public Circulo elMayor(Circulo c) {
void si no tiene), el nombre del mismo y una lista de argumentos
explcitos entre parntesis, separados por comas. Si no hay if (this.r>=c.r) // body
argumentos explcitos los parntesis se dejan vacos.
return this; // body
Los mtodos tienen visibilidad directa de las variables miembro del
else // body
objeto (el argumento implcito). Pueden acceder a ellas sin
referenciarlas. Tambin se pueden referenciar con this, de modo return c; // body
discrecional (this.r) o si alguna variable local o argumento las oculta.
El valor de retorno puede ser de un tipo primitivo o una referencia. } // fin del mtodo

En cualquier caso no puede haber ms que un nico valor de retorno (podr ser un objeto o array). Se
puede devolver tambin una referencia a un objeto con un nombre de interface. El objeto devuelto debe
pertenecer a una clase que implemente el interface. Se puede devolver como valor de retorno un objeto de
la clase del mtodo o de una sub-clase, pero nunca de una super-clase.
Los mtodos pueden definir variables locales. Su visibilidad (mbito) es desde la definicin al final del
bloque en el que se defininen. No hace falta inicializar las variables locales en el punto en que se definen,
pero el compilador no permite usarlas sin inicializarlas. A diferencia de las variables miembro, las variables
locales no se inicializan por defecto.
Native. Si un mtodo se declara native (Ej: public native void miMetodo();) no hay que incluir su
implementacin. El cdigo estar en una biblioteca dinmica (DLL), ficheros de funciones compiladas
normalmente en lenguajes distintos a Java. Es la forma de usar funciones de otros lenguajes desde Java.
Synchronized. Un mtodo declarado as (Ej: public synchronized double miMetodoSynch(){...}) especifica
que sobre un objeto no pueden ejecutarse simultneamente 2 mtodos sincronizados.
3.2.1.1. Sobrecarga de mtodos
Java permite sobrecarga de mtodos (overloaded). Son mtodos distintos con el mismo nombre, que se
diferencian por el nmero y/o tipo de argumentos. El ejemplo de la clase Circulo hay 2 casos de mtodos
sobrecargados: los 4 constructores y los 2 mtodos llamados elMayor(). A la hora de llamar a un mtodo
sobrecargado, Java identifica el correcto con los criterios:
1. Si existe el mtodo cuyos argumentos se ajustan exactamente al tipo de los argumentos de la llamada
(argumentos actuales), se llama a ese mtodo
2. Si no existe un mtodo que se ajuste exactamente, se intenta promover los argumentos actuales al tipo
inmediatamente superior (por ejemplo char a int, int a long, etc.) y se llama el mtodo correspondiente
3. Si slo existen mtodos con argumentos de un tipo ms restringido (p. ej. int en vez de long), el
programador debe hacer un cast explcito en la llamada, responsabilizndose de la ejecucin
4. El valor de retorno no influye en la eleccin del mtodo sobrecargado. Es imposible saber desde el
mtodo lo que se har con l. No es posible crear 2 mtodos sobrecargados que difieran en el valor de
retorno
Diferente de la sobrecarga de mtodos es la redefinicin. Una clase puede redefinir (override) un mtodo
heredado de una superclase. Esto es darle una nueva definicin. En este caso el mtodo debe tener
exactamente los mismos argumentos en tipo y nmero que el mtodo redefinido.
3.2.1.2. Paso de argumentos a mtodos
En Java los argumentos de los tipos primitivos se pasan siempre por valor. El argumento que se pasa no se
modifica. La forma de modificar una variable de tipo primitivo es incluirla como variable miembro en una
clase y pasar como argumento una referencia a un objeto de dicha clase.
Las referencias se pasan tambin por valor, pero permiten modificar los objetos referenciados. En Java no
se pueden pasar mtodos como argumentos a otros mtodos (en C/C++ se pueden pasar punteros a
mtodos). Lo que se puede hacer en Java es pasar una referencia a un objeto y usar sus mtodos. En un
mtodo se pueden crear variables locales de los tipos primitivos o referencias. Estas variables locales dejan
de existir al terminar la ejecucin del mtodo.
Los argumentos formales de un mtodo (las variables del header) tienen categora de variables locales del
mtodo. Si un mtodo devuelve this (un objeto de la clase) o una referencia a otro objeto, ese objeto puede
encadenarse con otra llamada a otro mtodo de la misma o diferente clase y as sucesivamente. En este
caso aparecern varios mtodos en la misma sentencia unidos por el operador punto.

Programacin en Java 23
El ejemplo muestra el uso del mtodo String numeroComoString = 8.978;
valueOf(String) de la clase java.lang. Float.
float p = Float.valueOf(numeroComoString).floatValue();
El mtodo valueOf(String) devuelve un objeto de la clase Float sobre el que se aplica el mtodo floatValue(),
que devuelve una variable primitiva de tipo float. El ejemplo anterior se poda desdoblar en las sentencias:
As se pueden encadenar llamadas a mtodos String numeroComoString = 8.978;
con el operador punto que, como todos los
Float f = Float.valueOf(numeroComoString);
operadores de Java excepto los de
asignacin, se ejecuta de izquierda a derecha. float p = f.floatValue();
3.2.2. Mtodos de clase (static)
Los mtodos que no actan sobre objetos con el operador punto se les llama mtodos de clase o static.
stos pueden recibir objetos de su clase como argumentos explcitos, pero no tienen argumento implcito ni
pueden usar la referencia this.
Ejemplo tpico de mtodos static son los de la clase java.lang.Math (sin(), cos(), exp(), etc.). Usualmente el
argumento de estos mtodos ser de tipo primitivo y se pasar como explcito. Estos mtodos no tienen
sentido como mtodos de objeto, sern static. Para llamarlos se suele usar el nombre de la clase, en vez
del nombre de un objeto de la clase (por ejemplo, Math.sin(ang).
En POO se evita informacin incorrecta al no inicializar variables. Java no permite que haya variables
miembro no inicializadas. Java inicializa siempre con valores por defecto. El segundo requisito de correcta
inicializacin de objetos es el uso de constructores.
Un constructor es un mtodo llamado automticamente al crear un objeto. Su misin es reservar memoria e
inicializar las variables miembro de la clase. No tienen valor de retorno y su nombre coincide con el de la
clase. Su argumento implcito es el objeto que se crea. Una clase suele tener varios constructores, que se
diferencian por el tipo y nmero de sus argumentos (ejemplo tpico de mtodos sobrecargados). Se llama
constructor por defecto al constructor que no tiene argumentos. El programador debe proporcionar en el
cdigo valores iniciales adecuados para todas las variables miembro.
Un constructor de una clase puede llamar, con this, a otro constructor previo definido en la misma clase. En
este contexto, this slo puede aparecer en la primera sentencia de un constructor. El constructor de una
sub-clase puede llamar al constructor de su super-clase con super con los argumentos apropiados. As, un
constructor slo inicializa las variables no heredadas.
Si no se define constructor para una clase, el compilador crea un constructor por defecto, inicializando las
variables al valor por defecto y las referencias a null. Si es necesario, se llama al constructor de la super-
clase para inicializar las variables heredadas. Los constructores tambin pueden ser public, private,
protected y package. Si es private, ninguna otra clase puede crear un objeto de esa clase. En este caso,
pueden disponerse mtodos public y static (factory methods) que llamen al constructor y devuelvan un
objeto de esa clase. En una clase, los constructores slo pueden ser llamados por otros constructores o
mtodos static. No pueden ser llamados por mtodos de objetos.
Java dispone una tercera va para evitar variables sin inicializar: los inicializadores, que pueden ser static
(para la clase) o de objeto.
Inicializador static. Es un recurso similar a un mtodo que se llama automticamente al crear la clase. Se
diferencia del constructor en que no es llamado para cada objeto, sino una sola vez para toda la clase.
Los tipos primitivos pueden inicializarse con asignaciones en la clase o el constructor, pero para inicializar
objetos o elementos ms complejos se puede usar inicializadores, ya que permiten gestionar excepciones.
Los inicializadores static se crean en la clase como mtodos static{
sin nombre, sin argumentos y sin valor de retorno, precedidos
System.loadLibrary("MyNativeLibrary");
de static y el cdigo entre llaves {...}, como en el ejemplo
mostrado a la derecha. }
En una clase pueden definirse varios inicializadores static, que se llamarn en el orden en que han sido
definidos. Los inicializadores static se pueden usar para dar valor a variables static. Adems se suelen usar
para llamar a mtodos nativos, escritos en otros lenguajes (llamando a los mtodos System.load() o
System.loadLibrary(), que leen las bibliotecas nativas).
Existen tambin inicializadores de objeto, que no llevan la palabra static. Se usan para clases annimas,
que por no tener nombre no tienen constructor. En este caso, los inicializadores de objeto se llaman cada
vez que se crea un objeto de la clase annima.

Programacin en Java 24
3.3. Objetos. Creacin, destruccin y finalizadores
El proceso de creacin de un objeto es:
1. Al crear el primer objeto de la clase o usar el primer mtodo o variable static se localiza la clase y se
carga en memoria
2. Se ejecutan los inicializadores static (slo una vez)
3. Cada vez que se quiere crear un nuevo objeto:
se reserva la memoria necesaria
se da valor por defecto a las variables miembro de los tipos primitivos
se ejecutan los inicializadores de objeto
se ejecutan los constructores
Java no dispone destructores como en C++. El sistema libera memoria automticamente de los objetos que
han perdido la referencia, que no tienen nombre que permita accederlos, por ejemplo al llegado al final del
bloque en el que se definieron, porque a la referencia se le ha asignado null o porque a la referencia se le
ha asignado la direccin de otro objeto. Esta caracterstica Java se conoce como garbage collection.
Es normal que distintas variables de tipo referencia apunten al mismo objeto. Java internamente cuenta las
referencias a cada objeto. El objeto podr ser borrado si el nmero de referencias es 0. No se sabe
exactamente cundo actuar el garbage collector. Si no falta memoria es posible que no se active. No es
conveniente confiarle tareas ms crticas, por lo que se le puede llamar explcitamente con el mtodo
System.gc(), pero el sistema lo considera como una sugerencia a la JVM.
Los finalizadores son mtodos que completan la labor del garbage collector. Se llaman automticamente al
destruir un objeto (antes que el sistema libere memoria). Se usan para operaciones de terminacin distintas
a la liberacin de memoria (p. ej. cerrar ficheros, conexiones de red, etc.). El garbage collector slo libera
memoria reservada con new. Si se ha reservado memoria con funciones nativas en C (por ejemplo malloc),
esa memoria hay que liberarla explcitamente con finalize().
Un finalizador es un mtodo de objeto (no static), sin valor de retorno (void), ni argumentos y que siempre
se llama finalize. Se llaman automticamente si han sido definidos en la clase. Para su tarea un finalizador
debera terminar siempre llamando al finalizador de su super-clase. Tampoco se puede saber el momento
preciso en que los finalizadores van a ser llamados. En ocasiones ser conveniente que el programador
realice esas operaciones de finalizacin de modo explcito mediante otros mtodos.
El mtodo System.runFinalization() sugiere a la JVM que ejecute los finalizadores de los objetos pendientes
(que han perdido referencia).
3.4. Packages
Un package es una agrupacin de clases. El usuario puede crear sus propios packages. Para que una clase
forme parte de un package, se sigue la sintaxis: package [nombre del package]. Debe ser la primera
sentencia del fichero sin contar comentarios ni lneas en blanco. Los nombres de los packages se suelen
escribir en minsculas, para distinguirlos de las clases, en maysculas.
Las clases de un package deben residir en el mismo directorio. Por eso, el nombre de un package puede
constar de varias palabras separadas por puntos, en relacin a la jerarqua de directorios en que estn las
clases. Es recomendable que los nombres de las clases Java sean nicos en Internet. El package facilita
esto, ya que se puede incluir el nombre del dominio, por ejemplo: es.cau.vgon.reserv.ord.
Las clases de un package se disponen en un directorio con el path del package. Por ejemplo, la clase,
es.cau.vgon.reserv.ord.Bubble.class estara en CLASSPATH\es\cau\vgon\reserv\ord\, siendo CLASSPATH
una variable de entorno del PC que establece la posicin absoluta de los directorios en los que hay clases
Java (de sistema o usuario), en este caso, los discos locales. Los packages poseen los objetivos de:
1. Agrupar clases relacionadas.
2. Evitar conflictos de nombres (el dominio de nombres Java es Internet). En caso de conflicto de nombres
entre clases importadas, el compilador obliga a cualificar en el cdigo los nombres de dichas clases con el
nombre del package.
3. Ayudar en el control de la accesibilidad de clases y miembros.
Con la sentencia import packname; se puede evitar usar nombres largos y colisin de nombres. Si se da
colisin de nombres de clases, Java da un error y obliga a usar los nombres de las clases cualificados con
el nombre del package.

Programacin en Java 25
Importar un package no hace que se carguen todas las clases del package: slo las clases public a usar. Al
importar un package no se importan los sub-packages: deben importarse explcitamente, pues en realidad
son packages distintos. P. ej., al importar java.awt no se importa java.awt.event. Es posible guardar en
jerarquas de directorios diferentes los ficheros *.class y *.java, con objeto p. ej. de no mostrar la situacin
del cdigo fuente. Los packages hacen referencia a los ficheros compilados *.class.
En un programa Java, una clase puede ser referida con su nombre completo (nombre del package ms el
de la clase, separados por punto), del mismo modo que sus variables y mtodos. Proceder as esengorroso
y hace ms difcil reutilizar cdigo y portarlo. La sentencia import permite abreviar los nombres de las
clases, variables y mtodos, evitando escribir el nombre del package. Se importan por defecto el package
java.lang y el package actual (clases del directorio actual). Existen 2 formas de usar import: para clase y
para package:
import es.cau.vgon.reserv.ord.Bubble.class; import es.cau.vgon.reserv.ord.*;
que deberan estar en el directorio es.cau.vgon.reserv.ord.
3.5. Herencia
La herencia permite definir una clase a partir de otra. Para indicarlo se usa la palabra extends. Ejemplo:
class CirculoGrafico extends Circulo {...}. Si una clase deriva de otra, hereda variables y mtodos, que
podrn redefinirse y aadirse nuevos. Es similar a que la clase derivada contuviera un objeto de la
superclase; la ampla con nuevos atributos y mtodos. Java permite mltiples niveles de herencia, pero no
herencia mltiple. Dada una clase, se pueden derivar tantas como se desee.
Las clases Java creadas tienen una superclase. Si no se indica con extends, se derivan de java.lang.Object,
la clase raz de la jerarqua Java. As todas las clases tienen mtodos heredados de Object. La composicin
(una clase contiene un objeto de otra clase) se diferencia de la herencia en que incorpora los datos del
objeto miembro, pero no sus mtodos o interface si se hace private. La clase Object tiene mtodos
interesantes que hereda cualquier objeto. Entre ellos:
Mtodos que pueden ser redefinidos.
clone(). Crea un objeto a partir de otro de la misma clase. El mtodo original heredado de Object
lanza una CloneNotSupportedException. Si se desea clonar una clase hay que implementar el
interface Cloneable y redefinir el mtodo clone(). Este mtodo debe hacer una copia miembro a
miembro del objeto original. No debera llamar al operador new ni a constructores.
equals(). Indica si 2 objetos son iguales o no. Devuelve true si lo son tanto si son referencias al
mismo objeto como si son objetos distintos con iguales valores de las variables miembro.
toString(). Devuelve un String que contiene una representacin del objeto como cadena de
caracteres, p. ej. para imprimirlo o exportarlo.
finalize(). Ya visto.
Mtodos que no pueden ser redefinidos (mtodos final).
getClass(). Devuelve un objeto de la clase Class, al cual se pueden aplicar mtodos para determinar
el nombre de la clase, su super-clase, las interfaces implementadas, etc. Se puede crear un objeto
de la misma clase que otro sin saber de qu clase es.
notify(), notifyAll() y wait(). Mtodos relacionados con hilos (threads).
Una clase puede redefinir los mtodos heredados de su super-clase que no sean final. El mtodo redefinido
en la clase sustituye funcionalmente al heredado. Pueden ser accedidos con la palabra super desde la clase
derivada, aunque slo se puede invocar el nivel inmediatamente superior. Tambin pueden ampliar los
derechos de acceso de la super-clase (p. ej. ser public, en vez de protected o package), pero nunca
restringirlos. Los mtodos de clase o static no pueden ser redefinidos en las clases derivadas.
3.5.1. Clases y mtodos abstractos. Constructores en clases derivadas
Una clase abstracta (abstract) es aquella que no permite crear objetos. Permite que otras clases deriven de
ella, proporcionndoles un arquetipo o patrn a seguir y mtodos de utilidad general. Las clases abstractas
se declaran anteponindo la palabra abstract. P. ej. public abstract class Geometria { ... }. Una clase
abstract puede tener mtodos definidos como abstract, en cuyo caso no se implementan.
Si una clase tiene mtodos abstract es obligatorio que sea abstract. En cualquier clase derivada ese mtodo
debe ser redefinido, o volver a declararse abstract (mtodo y sub-clase). Una clase abstract puede tener
mtodos no abstract. Aunque no se puedan crear objetos de esa clase, sus derivadas heredarn el mtodo
para ser usado. Como los mtodos static no pueden ser redefinidos, un mtodo abstract no puede ser static.

Programacin en Java 26
Un constructor de una clase puede llamar con this a otro previamente definido en la misma clase. As, this
slo puede aparecer en la primera sentencia de un constructor. Anlogamente el constructor de una clase
derivada puede llamar al constructor de su super-clase con super(), con los argumentos apropiados. De
esta forma, un constructor slo tiene que inicializar directamente las variables no heredadas.
La sentencia de llamada al constructor de la superclase debe ser la primera, excepto si se llama a otro
constructor de la misma clase con this(). Si no se incluye, Java hace automticamente una llamada al
constructor por defecto de la superclase (super). Esta llamada encadena a los constructores de las
superclases hasta el origen de la jerarqua de clases, esto es hasta el constructor de Object.
Si no se prepara un constructor por defecto, el compilador crea uno, inicializando las variables de los tipos
primitivos a valores por defecto y strings y dems referencias a objetos a null. Antes, incluir una llamada al
constructor de la superclase. En el proceso de finalizacin o liberacin de recursos (diferentes de memoria
reservada con new, de la que se encarga el garbage collector) es importante llamar a los finalizadores de
las distintas clases, normalmente en orden inverso al de llamada de los constructores. Esto hace que el
finalizador de la subclase realice sus tareas primero y luego llame al finalizador de la superclase en la forma
super.finalize(). Los mtodos finalize() deben ser al menos protected, ya que el mtodo finalize() de Object
lo es, y no est permitido reducir los permisos de acceso en la herencia.
Las variables declaradas como final no pueden cambiar su valor una vez inicializadas. Existen otros 2 usos
de la palabra final. Una clase declarada final no puede tener clases derivadas. Esto se puede hacerse por
motivos de seguridad o de eficiencia, ya que si el compilador sabe que los mtodos no van a ser redefinidos
puede hacer optimizaciones adicionales. Anlogamente, un mtodo declarado como final no puede ser
redefinido por una clase que derive de su propia clase.
3.5.2. Interfaces
Una interface es un conjunto de declaraciones de mtodos sin definicin. Tambin puede definir constantes,
que son implcitamente public, static y final y siempre se inicializan en la declaracin. Estos mtodos definen
un tipo de conducta. Todas las clases que implementan un interface dado estn obligadas a proporcionar
una definicin de sus mtodos adquiriendo una conducta particular. Una clase puede implementar varias
interfaces. Para indicarlo se ponen los nombres de las interfaces, separados por comas, detrs de la
palabra implements, que a su vez va siempre a la derecha del nombre de la clase o del nombre de la
superclase en el caso de herencia, como en el ejemplo.
Una interface y una clase abstract pueden contener varias public class CirculoGrafico extends Circulo
declaraciones de mtodos (la clase abstract puede adems
implements Dibujable, Cloneable {
definirlos). Esto permite, a veces, que se pueda optar por
implementar el cdigo con cualquiera de ambas opciones. ...
Pero, existen tambin diferencias importantes: }
1. Una clase no puede heredar de 2 clases abstract, pero s puede heredar de una clase abstract e
implementar una interface, o bien implementar 2 o ms interfaces
2. Una clase no puede heredar mtodos (definidos) de una interface, aunque s constantes
3. Las interfaces permiten ms flexibilidad para conseguir que 2 clases se comporten igual, de forma
independiente de su situacin en la jerarqua de clases de Java
4. Las interfaces permiten publicar el comportamiento de una clase desvelando un mnimo de informacin
5. Las interfaces tienen una jerarqua propia, independiente y ms flexible que la de las clases, ya que
permiten herencia mltiple
6. En polimorfismo las referencias de un tipo interface se pueden usar de modo similar a las clases abstract
Una interface se define de modo similar a las clases. En el cuadro se muestra la definicin de la interface
Dibujable presentada anteriormente. Cada interface public debe ser definida en un fichero *.java con el
mismo nombre de la interface. Los nombres de las interfaces suelen comenzar tambin con mayscula.
Las interfaces no admiten ms que los modificadores de // fichero Dibujable.java
acceso public y package. Si la interface no es public no ser
import java.awt.Graphics;
accesible desde fuera del package (tendr accesibilidad por
defecto; package). Los mtodos declarados en una interface public interface Dibujable {
son siempre public y abstract, de modo implcito. Entre las
interfaces existe una jerarqua (independiente de la de las public void setPosicion(double x, double y);
clases) que permite herencia simple y mltiple. Cuando una public void dibujar(Graphics dw);
interface deriva de otra, incluye todas sus constantes y
declaraciones de mtodos. }

Programacin en Java 27
Una interface puede derivar de varias interfaces. Para la herencia de interfaces se usa la palabra extends,
seguida del nombre de las interfaces de las que deriva, separadas por comas. Una interface puede ocultar
una constante definida en una superinterface definiendo otra constante con el mismo nombre. De la misma
forma puede ocultar, redeclarndolo, un mtodo heredado de una superinterface.
Las interfaces no deberan ser modificadas ms que en caso de extrema necesidad. Si se modifican, por
ejemplo aadiendo alguna nueva declaracin de un mtodo, las clases que hayan implementado dicha
interface dejarn de funcionar, a menos que lo implementen.
Las constantes definidas en una interface se pueden usar en cualquier clase aunque no la implemente
precedindolas del nombre de la interface (P.ej.: area = 2.0*Dibujable.PI*r;). En las clases que implementan
la interface las constantes se pueden usar directamente, como las constantes de la clase. A veces se crean
interfaces para agrupar constantes simblicas relacionadas (similar al enum de C/C++).
En relacin al polimorfismo, el nombre de un interface se puede usar como un nuevo tipo de referencia. El
nombre de un interface puede ser usado en lugar del nombre de cualquier clase que la implemente, aunque
su uso estar restringido a los mtodos del interface. Un objeto de ese tipo puede tambin usarse como
valor de retorno o argumento de un mtodo.
3.7. Clases internas
Una clase interna es la definida dentro de otra clase, llamada contenedora, en alguna variante como
muestra el cuadro, en su forma general. Adems de su utilidad en s, las clases internas se usan mucho en
el modelo de eventos. Hay cuatro tipos de clases internas:
1. Clases internas static. class ClaseContenedora {
2. Clases internas miembro. ...
3. Clases internas locales. class ClaseInterna {
4. Clases annimas. ...
El trmino clase contenedora o global referencia la clase que contiene }
a la clase interna. La JVM no entiende de clases internas. Por ello, el
...
compilador convierte estas clases en globales, contenidas en ficheros
*.class cuyo nombre es ClaseContenedora$ClaseInterna.class. }
Esta conversin inserta variables ocultas, mtodos y argumentos en los constructores. Lo ms importante
se refiere al nombre de los ficheros que aparecen en el directorio donde se realiza la compilacin, que
pueden resultar sorprendentes si no se conoce su origen.
3.7.1. Clases e interfaces internas static
Tambin conocidas como nested classes (clases anidadas). Slo pueden ser creadas dentro de otra clase
al mximo nivel, en el bloque de definicin de la clase contenedora; no en un bloque ms interno. Es posible
definirlas en una interface contenedora. Este tipo de clases internas se definen con static. Las interfaces
internas son implcitamente static. Para usar su nombre desde fuera de la clase contenedora hay que
precederlo por el nombre de la clase contenedora y el punto. Este tipo de relacin entre clases permite
agrupar varias clases en una clase ms general. Lo mismo para interfaces internas.
Las clases internas static pueden ver y usar los miembros static de la clase contenedora. No se necesitan
objetos de la clase contenedora para crear objetos de la clase interna static. Los mtodos de la clase interna
static no pueden acceder directamente a los objetos de la clase contenedora, caso de que los haya: deben
disponer de una referencia a dichos objetos, como cualquier otra clase.
La sentencia import puede usarse para importar una clase interna ... implements List.Linkable
static, como si se importara una clase de un package (con el punto).
Para importarla se usa:
Por ejemplo, si la interface Linkable es interna a la clase List, para
implementar dicha interface se expresara como en el cuadro. import List.*;
Otras caractersticas importantes son: o bien import List.Linkable;
1. Clases e interfaces internas pueden definirse en interfaces y clases contenedoras
2. Multinivel: una clase interna static puede ser clase contenedora de otra clase interna static, etc.
3. Clases e interfaces internas static pertenecen al package de la clase contenedora
4. Pueden usarse los calificadores final, public, private y protected. sta es una forma ms de controlar el
acceso a ciertas clases. A continuacin se presenta un ejemplo de clase interna static.

Programacin en Java 28
// fichero ClasesIntStatic.java class ClasesIntStatic {
class A { public static void main(String [] arg) {
int i=1; // variable miembro de objeto A a1 = new A(11), a2 = new A(12);
static int is=-1; // variable miembro de clase println("a1.i=" + a1.i + " a2.i=" + a2.i);
public A(int i) {this.i=i;} // constructor // 2 formas de crear objetos de Bs
public void printA(Bs unBs) { A.Bs b1 = new A.Bs(-10); // obligatorio A.Bs
// al mtodo printA hay que pasarle la referencia a A.Bs b2 = a1.new Bs(-11); // b2 independiente de a1
// los objetos de la clase interna static // referencia directa a los objetos b1 y b2
System.out.println("i="+i+" unBs.j="+unBs.j); println("b1.j=" + b1.j + " b2.j=" + b2.j);
}
// definicin de clase interna static // los mtodos de la clase Bs acceden directamente
// a las variables de la clase A slo si son static
static class Bs {
b1.printBs(); // escribe: j=-10 is=-1
int j=2;
b2.printBs(); // escribe: j=-20 is=-1
public Bs(int j) {this.j=j;}
// a los mtodos de A hay que pasarles referencias
// los mtodos de la clase Bs no acceden a la i;
// a los objetos de Bs, para identificarlos
// es una variable de objeto. S acceden a is
a1.printA(b1); // escribe: i=11 unBs.j=-10
public void printBs() {
a1.printA(b2); // escribe: i=11 unBs.j=-11
System.out.println(" j=" + j + " is=" + is);
} // main
}
public static void println(String str)
} // fin clase Bs
{System.out.println(str);}
} // fin clase contenedora A
} // ClasesIntStatic
3.7.2. Clases internas miembro (no static)
Tambin llamadas clases internas, sin ms, son las definidas al mximo nivel de la clase contenedora, sin
static. No existen interfaces internas de este tipo y no pueden tener variables static. Caracterstica es que
cada objeto de la clase interna existe siempre dentro de slo un objeto de la clase contenedora. Pero un
objeto de la clase contenedora puede relacionarse con varios objetos de la clase interna. Esto es importante
para estudiar la relacin entre clases interna y contenedora respecto al acceso a las variables miembro:
1. Debido a la relacin uno a uno, los mtodos de la clase interna ven directamente las variables miembro
del objeto de la clase contenedora, sin necesidad de cualificarlos
2. Los mtodos de la clase contenedora no ven directamente las variables miembro de los objetos internos:
necesitan cualificarlos con la referencia correspondiente. Esto es debido a la relacin uno a varios.
3. Clases distintas a la contenedora e interna pueden usar directamente los objetos de la clase interna, sin
cualificarlos con el objeto o nombre de la clase contenedora. Se puede acceder a los objetos de la clase
interna aunque se pierda la referencia al objeto de la clase contenedora al que estn asociados.
En cuanto al acceso:
1. Las clases internas pueden ser private y protected (las normales slo pueden ser public y package),
permitiendo nuevas posibilidades de encapsulacin
2. Los mtodos de las clases internas acceden a todos los miembros, incluso private, de la contenedora
3. La clase contenedora puede acceder (si dispone de una referencia) a todas las variables miembro
(incluso private) de sus clases internas
4. Una clase interna puede acceder a los miembros (incluso private) de otras clases internas definidas en la
misma clase contenedora
Otras caractersticas de las clases internas:
1. Una clase interna miembro puede contener otra clase interna miembro, hasta el nivel que se desee (no
son recomendables muchos niveles)

Programacin en Java 29
2. En la clase interna, la palabra this se refiere a su objeto. Para acceder al objeto de la contenedora se usa
ClaseContenedora.this
3. Para crear un nuevo objeto de la clase interna se puede usar new, precedido de la referencia al objeto de
la clase contenedora que contendr el nuevo objeto: unObjCC.new(). El tipo del objeto es el nombre de la
clase contenedora seguido del nombre de la clase interna, por ejemplo: ClaseCont.ClaseInt unObjClInt =
unObjClaCont.new ClaseInt(...);
4. Sea B una clase interna de A y A a = new A(); // se crea un objeto de la clase A
C una clase interna de B. Un
A.B b = a.new B(); // b es un objeto de B dentro de a
ejemplo de creacin de objetos
de las 3 clases sera: A.B.C c = b.new C(); // c es un objeto de C dentro de b
5. No se puede crear un objeto de la clase interna sin referencia a un objeto de la contenedora. Los
constructores de la clase interna tienen como argumento oculto una referencia al objeto de la contenedora
6. La palabra super ahora entiende que una clase derivada de una interna, su constructor no puede llamar a
super directamente. El compilador no puede crear un constructor por defecto. Al constructor hay que pasarle
una referencia a la contenedora de la clase interna superclase y con esa referencia ref llamar a ref.super()
Las clases internas pueden derivar de clases distintas a la contenedora. Caso en que:
1. Las clases internas constituyen una especie de segunda jerarqua de clases Java. Pertenecen a la clase
contenedora y ven sus variables. Y al derivar de otra clase distinta a la contenedora deben evitar conflictos
con los nombres. En caso de conflicto entre un nombre heredado y uno de la clase contenedora, el nombre
heredado tiene prioridad
2. En caso de conflicto de nombres, Java obliga a usar this (this.name) para referirse a la variable o mtodo
heredado y para el miembro de la clase contenedora NombreClaseCont.this.name
3. Si una clase contenedora deriva de una superclase con una clase interna, la interna de la subclase puede
a su vez derivar de la clase interna de la superclase y redefinir los mtodos que necesite
El uso de las clases internas miembro tiene las siguientes restricciones:
1. Las clases internas no pueden tener el mismo nombre que la contenedora o package
2. Las clases internas no pueden tener miembros static: variables, mtodos o clases
El cuadro muestra un ejemplo de uso de clases internas miembro.
// fichero ClasesInternas.java class ClasesInternas {
class A { // clase contenedora public static void main(String [] arg) {
int i=1; // variable miembro A a1 = new A(11); A a2 = new A(12);
public A(int i) {this.i=i;} // constructor println("a1.i=" + a1.i + " a2.i=" + a2.i);
// los mtoodos de la contenedora necesitan A.B b1 = a1.new B(-10), b2 = a1.new B(-20);
// referencia a los objetos de la clase interna println("b1.j=" + b1.j + " b2.j=" + b2.j);
public void printA(B unB) { // los mtodos de la clase interna pueden acceder a
// las variables del objeto de la contenedora
System.out.println("i="+i+" unB.j="+unB.j);
b1.printB(); // escribe: i=11 j=-10
// s acepta unB.j
b2.printB(); // escribe: i=11 j=-20
}
a1.printA(b1); a1.printA(b2);
protected class B { // Clase interna
A a3 = new A(13); A.B b3 = a3.new B(-30);
int j=2;
println("b3.j=" + b3.j);
public B(int j) {this.j=j;} // constructor
a3 = null; b3.printB(); // escribe: i=13 j=-30
public void printB() {
a3 = new A(14); b3.printB(); // escribe: i=13 j=-30
System.out.println("i=" + i + " j=" + j); // sabe qu es j
} // fin de main()
}
public static void println(String str)
} // fin clase B
{System.out.println(str);}
} // fin clase contenedora A
} // fin clase ClasesInternas

Programacin en Java 30
3.7.3. Clases internas locales y clases annimas
Las clases internas locales (o locales) no se declaran en otra clase al mximo nivel. Se hace en un bloque
de cdigo, en general un mtodo, aunque pueden crearse en un inicializador static o de objeto. Adems:
1. Slo son visibles y utilizables en el bloque de cdigo en que se definen. Los objetos de la clase local
deben crearse en el mismo bloque en la clase se define
2. Tienen acceso a todas las variables miembro y mtodos de la clase contenedora. Pueden ver tambin los
miembros heredados por la clase interna local y la contenedora
3. Pueden usar las variables locales y argumentos de mtodos visibles en ese bloque de cdigo, pero slo
si son final (la clase local trabaja con sus copias de las variables locales; por eso se exige)
4. Un objeto de una clase local slo puede existir en relacin con un objeto de la clase contenedora, que
exista previamente
5. La palabra this se puede usar en la misma forma que en las clases internas, pero no new y super
Restricciones en el uso de clases locales:
1. No pueden tener el mismo nombre que ninguna de sus clases contenedoras
2. No pueden definir variables, mtodos y clases static
3. No pueden ser declaradas public, protected, private o package, pues su visibilidad es siempre la de las
variables locales; la del bloque en que han sido definidas
Las clases internas locales se usan para definir clases Adapter en el AWT. El cuadro muestra un ejemplo.
// fichero ClasesIntLocales.java
class A {
int i=-1; // variable miembro class ClasesIntLocales {
public A(int i) {this.i=i;} // constructor public static void main(String [] arg) {
public void getAi(final long k) { // argumento final // se crean 2 objetos de la clase contenedora
final double f=3.14; // variable local final A a1 = new A(-10);
class BL { // clase local A a2 = new A(-11);
int j=2; public BL(int j) {this.j=j;} // constructor a1.getAi(1000); // llama al mtodo getAi()
public void printBL() { a2.getAi(2000); // crea y accede a un objeto
// de la clase local
System.out.println(" j="+j+" i="+i+" f="+f+" k="+k);
} // fin de main()
}
public static void println(String str)
} // fin clase BL
{System.out.println(str);}
BL bl = new BL(2*i); // se crea un objeto de BL
} // fin clase ClasesIntLocales
bl.printBL(); // imprime datos del objeto
} // fin getAi
} // fin clase contenedora A
Las clases annimas son similares a las locales, pero sin nombre. En las locales primero se define la clase
y luego se crean objetos. En las clases annimas se unen los procesos. Como la clase no tiene nombre slo
se puede crear un objeto, ya que no se definen constructores. Se usan con frecuencia para definir clases y
objetos en el AWT que gestionen los eventos de los componentes de la interface de usuario. No hay
interfaces annimas. Formas de definir una clase annima son las siguientes.
1. En una expresin incluida en una asignacin o la llamada a un mtodo. Se incluye la palabra new
seguida de la definicin entre llaves de la clase annima
2. Con la palabra new seguida del nombre de la clase de la que hereda (sin extends) y su definicin entre
llaves. El nombre de la superclase puede ir seguido de argumentos para su constructor entre parntesis
3. Con la palabra new seguida del nombre del interface que implementa (sin implements) y su definicin
entre llaves. En este caso la clase annima deriva de Object y el nombre del interface va seguido de
parntesis vacos, pues el constructor de Object no tiene argumentos

Programacin en Java 31
Para clases annimas compiladas, el compilador produce ficheros asignando un nmero correlativo a cada
clase annima con nombres del tipo ClaseContenedora$1.class. Debe prestarse atencin a la caligrafa de
definicin de clases annimas, pues al no tener nombre suelen ser difciles de leer e interpretar. Se
aconseja que la palabra new est en la misma lnea que el resto de la expresin; que las llaves se abran en
la misma lnea que new, despus del cierre del parntesis de los argumentos del constructor; que el cuerpo
de la clase se sangre o indente respecto a las lneas anteriores de cdigo por legibilidad; que el cierre de las
llaves vaya seguido por el resto de la expresin en la que se ha definido la clase. A continuacin se muestra
un ejemplo de clase annima con el AWT.
La clase annima, derivada de Object, implementa unObjeto.addActionListener( new ActionListener() {
la interface ActionListener. Las clases annimas se
public void actionPerformed(ActionEvent e) {
usan en lugar de las locales para poco cdigo, de
las que slo hace falta un objeto. No pueden tener ...
constructores, pero s inicializadores static o de
objeto. Adems de las citadas, tienen restricciones }
similares a las clases locales. });
3.8. Permisos de acceso en java
La encapsulacin en POO es la propiedad de ocultar la informacin que no interesa sea manipulada por el
usuario. Para controlar esa manipulacin, se dispone de los permisos de acceso Java.
Acceso a packages. Hace referencia a la accesibilidad fsica entre mquinas y sus permisos de acceso a
ficheros. En este sentido, un package es accesible si sus directorios y ficheros son accesibles
(disponibilidad y permiso). Adems, sern accesibles los packages listados en la variable CLASSPATH.
Acceso a clases o interfaces. En principio, cualquier clase o interface de un package, sea public o no, es
accesible para las dems clases del package. Una clase public es accesible a cualquier clase si su package
es accesible. Clases e interfaces slo pueden ser public o package (la opcin por defecto).
Acceso a variables y mtodos miembros de una clase. Se distinguen 3 casos.
Desde dentro de la propia clase
1. Los miembros de una clase son accesibles (sin cualificar o con this) desde dentro de la propia
clase. Los mtodos no necesitan que las variables miembro sean pasadas como argumento
2. Los miembros private de una clase slo son accesibles para la propia clase
3. Si el constructor de una clase es private, slo un mtodo static de la clase puede crear objetos
Desde una subclase.
Las subclases heredan los miembros private de su superclase, pero slo pueden acceder a ellos a
travs de mtodos public, protected o package de la superclase
Desde otras clases del package
Desde una clase de un package se tiene acceso a todos los miembros que no sean private de las
dems clases del package
Desde otras clases fuera del package
1. Los mtodos y variables son accesibles si la clase es public y el miembro es public
2. Tambin son accesibles si la clase que accede es una subclase y el miembro es protected
La muestra un resumen de los permisos de acceso en Java.
Visibilidad public protected private default
Desde la propia clase SI SI SI SI
Desde otra clase en el propio package SI SI NO SI
Desde otra clase fuera del package SI NO NO NO
Desde una subclase en el propio package SI SI NO SI
Desde una subclase fuera del propio package SI SI NO NO
3.9. Transformaciones de tipo: casting
En Java se realizan de modo automtico conversiones implcitas de un tipo a otro de ms precisin, por
ejemplo de int a long, float a double, etc. cuando se mezclan variables de distintos tipos en expresiones

Programacin en Java 32
matemticas o al ejecutar sentencias de asignacin en las que el miembro izquierdo tiene un tipo distinto
(ms amplio) que el resultado de evaluar el miembro derecho.
Las conversiones de un tipo de mayor precisin a otro de menor requieren sentencia explcita, pues son
conversiones inseguras (p. ej. pasar a short un int, hay que asegurar que puede representarse con el
nmero de cifras binarias de short). Estas conversiones explcitas de tipo son el casting y se hace poniendo
el tipo al que se desea transformar entre parntesis. Por ejemplo {long result; result = (long) (a/(b+c));}. A
diferencia de C/C++, en Java no se puede convertir un tipo numrico a boolean. La conversin de strings
(texto) a nmeros se estudia posteriormente.
3.10. Polimorfismo
El polimorfismo se refiere a la relacin entre la llamada a un mtodo y el cdigo que se ejecuta con ella.
Esta relacin se denomina vinculacin (binding). Puede ser temprana (en compilacin) o tarda (en
ejecucin). Con funciones normales o sobrecargadas se usa vinculacin temprana (posible y ms eficiente).
Con funciones redefinidas se usa siempre vinculacin tarda, excepto si el mtodo es final.
El polimorfismo es la opcin por defecto en Java. La vinculacin tarda posibilita que, con un mtodo
declarado en una clase base (o interface) redefinido en clases derivadas (o que implementan esa interface),
sea el tipo de objeto y no el tipo de referencia el que determine qu definicin del mtodo se usa.
El tipo del objeto al que apunta una referencia slo se conoce en tiempo de ejecucin. Por eso el
polimorfismo requiere evaluacin tarda, permitiendo al programador separar contextos de constantes,
favoreciendo la ampliacin, mantenimiento y reutilizacin del cdigo. El polimorfismo puede implementarse
con referencias de superclases normales, abstract e interfaces. Por su mayor flexibilidad e independencia
de la jerarqua de clases estndar, las interfaces permiten ampliar las posibilidades del polimorfismo.
El polimorfismo se basa en el uso de referencias ms amplias que los objetos a los que apuntan. Pero
posee una limitacin importante: el tipo de la referencia (clase abstracta, base o interface) limita los mtodos
que se pueden usar y las variables miembro a las que se puede acceder. Por ejemplo, un objeto puede
tener una referencia a un tipo interface, slo en caso de que su clase o una de sus superclases implemente
dicha interface. Un objeto cuya referencia es un tipo interface slo puede usar los mtodos definidos en
dicha interface. De otro modo, ese objeto no puede usar variables ni mtodos propios de su clase. De esta
forma las referencias de tipo interface definen, limitan y unifican la forma de uso de objetos de clases muy
distintas que implementan dicha interface.
Si se desea usar todos los mtodos y acceder a todas las variables que la clase de un objeto permite, hay
que usar un cast explcito, que convierta su referencia ms general en la del tipo especfico del objeto. De
aqu una parte importante del inters del cast entre objetos. Para la conversin entre objetos de distintas
clases, Java exige que dichas clases estn relacionadas con herencia. Se realiza una conversin implcita o
automtica de una subclase a una superclase siempre que se necesite, ya que el objeto de la subclase
tiene toda la informacin necesaria para usarse en lugar de un objeto de la superclase. No importa que la
superclase no sea capaz de contener toda la informacin de la subclase.
La conversin en sentido contrario (un objeto de una superclase donde se espera encontrar uno de la
subclase) debe hacerse de modo explcito y puede producir errores por falta de informacin o mtodos. Si
falta informacin, se obtiene una ClassCastException. No se puede acceder a las variables exclusivas de la
subclase con una referencia de la superclase. Slo se pueden usar mtodos definidos en la superclase,
aunque la ejecucin de esos mtodos sea el cdigo de la subclase.
Por ejemplo, sea un objeto de la subclase B referenciado con un nombre de la superclase A: A a = new B();.
En este caso el objeto dispone de ms informacin de la que la referencia a le permite acceder (p.ej., una
nueva variable miembro j de B). Para acceder a esa informacin adicional hay que hacer un cast explcito
en la forma (B)a. Para imprimir esa variable j habra que escribir (los parntesis son necesarios):
System.out.println( ((B)a).j );.
Un cast de un objeto a la superclase x // se accede a la x de C
puede permite usar variables (no
this.x // se accede a la x de C
mtodos) de la superclase, aunque estn
redefinidos en la subclase. Sea una clase super.x // se accede a la x de B. Slo se sube un nivel
C derivada de B, derivada de A. Las 3
((B)this).x // se accede a la x de B
definen una variable x. En este caso, si
desde el cdigo de la subclase C se usa: ((A)this).x // se accede a la x de A

Programacin en Java 33
4. CLASES DE UTILIDAD
La programacin Java siempre parte de la infraestructura de su API. Se describen algunas clases tiles.
4.1. Arrays
Los arrays de Java (vectores, matrices e hipermatrices) se tratan como objetos de caractersticas propias de
una clase predefinida. Pueden ser asignados a objetos de la clase Object y los mtodos de Object pueden
ser usados con arrays.
Los arrays se crean con el operador new seguido del tipo y nmero de elementos y se puede acceder al
nmero de elementos de un array con la variable miembro implcita length (vect.length). A los elementos de
un array se accede con los corchetes [] y un ndice (de 0 a length-1).
Se pueden crear arrays de objetos. En principio ser un array de referencias que hay que completar con el
operador new. Los elementos de un array se inicializan al valor por defecto del tipo correspondiente (0 para
valores numricos, nulo para char, false para boolean, null para Strings y referencias). Como todos los
objetos, los arrays se pasan a los mtodos por referencia. Se pueden crear arrays annimos (p. ej. un
nuevo array como argumento actual en la llamada a un mtodo).
Los arrays se pueden inicializar con valores entre llaves separados por comas. Los arrays de objetos se
pueden inicializar con varias llamadas a new entre llaves. Si se igualan dos referencias a un array no se
copia el array, se genera un array con dos nombres, apuntando al mismo objeto.
Para crear una referencia a un array existen 2 formas, como double[] x; double x[];
se muestra en la primera lnea del cuadro. Para crearlo, se
x = new double[100];
usa el operador new. Ambas, la creacin de la referencia y
el propio array, se pueden resumir como en la ltima lnea. double[] x = new double[100];
Los siguientes muestran ejemplos de creacin de arrays.
// array de 10 enteros, por defecto inicializados a 0 // array de 5 objetos
int v[] = new int[10]; MiClase listaObj[] = new MiClase[5]; // los 5 a null
// arrays inicializados con valores for( i = 0 ; i < 5;i++)
int v[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; listaObj[i] = new MiClase(...);
String dias[] = {"lunes", "martes", "miercoles", // array annimo
"jueves", "viernes", "sabado", "domingo"};
obj.metodo(new String[]={"uno", "dos", "tres"});
Los arrays bidimensionales se crean con reserva dinmica de memoria. En Java una matriz es un vector de
vectores fila, o un vector de referencias a los vectores fila.
As, cada fila podra tener un nmero de elementos diferente. Una int[][] mat;
matriz se puede crear directamente en la forma int [][] mat = new
mat = new int[nfilas][];
int[3][4]; o bien dinmicamente, como en el cuadro. Primero se
crea la referencia a la matriz, indicndolo con un doble corchete. for (int i=0; i<nfilas; i++);
Luego se crea el vector de referencias a las filas y por fin, se
reserva memoria para los vectores correspondientes a las filas. mat[i] = new int[ncols];

Los siguientes muestran ejemplos de creacin de arrays bidimensionales.


En el caso de una matriz b, b.length es el nmero double mat[][] = new double[3][3];
de filas y b[0].length el nmero de columnas (de
int [][] b = {{1, 2, 3},{4, 5, 6},};
la fila 0). Los arrays bidimensionales pueden
contener tipos primitivos de cualquier tipo u int c = new[3][]; // crea el array de referencias a arrays
objetos de cualquier clase.
c[0] = new int[5]; c[1] = new int[4]; c[2] = new int[8];
4.2. Clases string y stringbuffer
Las clases String y StringBuffer se orientan a manejar cadenas de caracteres. La primera a cadenas de
caracteres constantes y StringBuffer permite cambiar la cadena. String es ms eficiente y menos verstil.
Ambas clases pertenecen al package java.lang; no hay que importarlas. El operador de concatenacin (+)
entre objetos de tipo String usa internamente objetos de StringBuffer y el mtodo append. Los mtodos de
String se pueden usar directamente sobre literals (cadenas entre comillas), como "Hola".length().
Los objetos de la clase String se pueden crear a partir de cadenas constantes o literals, definidas entre
dobles comillas ("Hola"). Java crea siempre un objeto String al encontrar una cadena entre comillas.

Programacin en Java 34
En el cuadro se muestran 2 formas de crear objetos de la clase String str1 = "Hola"; // ms eficaz
String. El primero es ms eficiente, porque al encontrar un texto
String str2 = new String("Hola");
entre comillas se crea automticamente un objeto String.
En la prctica, con new se llama al constructor 2 veces. Tambin se pueden crear objetos de String con
constructores de la clase, a partir de objetos StringBuffer, y de arrays de bytes o chars. La tabla siguiente
muestra los mtodos ms importantes de la clase String. Existen mtodos, como System.out.println que
exigen que su argumento sea un objeto de la clase String. Si no lo es, habr que convertirlo.
Mtodos de String Funcin
String(...) Constructores a partir de arrays de bytes o caracteres
String(String str), String(StringBuffer sb) Costructores a partir de un objeto String o StringBuffer
charAt(int) Devuelve el carcter en la posicin especificada
getChars(int, int, char[], int) Copia los caracteres indicados en la posicin indicada de un
array de caracteres
indexOf(String, [int]) Devuelve la posicin en la que aparece por primera vez un String
en otro String, a partir de una posicin dada (opcional)
lastIndexOf(String, [int]) Devuelve la ltima vez que un String aparece en otro empezando
en una posicin y hacia el principio
length() Devuelve el nmero de caracteres de la cadena
replace(char, char) Sustituye un carcter por otro en un String
startsWith(String) Indica si un String comienza con otro String o no
substring(int, int) Devuelve un String extrado de otro
toLowerCase() Convierte en minsculas (puede tener en cuenta el locale)
toUpperCase() Convierte en maysculas (puede tener en cuenta el locale)
trim() Elimina los espacios en blanco al comienzo y final de la cadena
valueOf() Devuelve la representacin como String de sus argumentos.
Admite Object, arrays de caracteres y los tipos primitivos
El locale citado en la tabla es la forma que Java tiene para adaptarse a las peculiaridades de los idiomas
distintos al ingls, fechas y horas, unidades monetarias, etc.
La clase StringBuffer se usa prcticamente siempre que se desea modificar una cadena de caracteres.
Completa los mtodos de la clase String, que slo realizan operaciones sobre el texto si no implica aumento
o disminucin del nmero de letras del String. La Tabla muestra los mtodos destacados de StringBuffer.
Mtodos de StringBuffer Funcin
StringBuffer(), StringBuffer(int), Constructores
StringBuffer(String)
Tiene muchas definiciones diferentes para aadir un String o una variable
append(...)
(int, long, double, etc.) a su objeto
capacity() Devuelve el espacio libre del StringBuffer
charAt(int) Devuelve el carcter en la posicin especificada
Copia los caracteres indicados en su posicin de un array de caracteres
getChars(int, int, char[], int)
insert(int, ) Inserta un String o un valor (int, long, double, ...) en la posicin
especificada de un StringBuffer
length() Devuelve el nmero de caracteres de la cadena
reverse() Cambia el orden de los caracteres
setCharAt(int, char) Cambia el carcter en la posicin indicada
setLength(int) Cambia el tamao de un StringBuffer
toString() Convierte en objeto de tipo String

Programacin en Java 35
4.3. Wrappers y clase Math
Wrappers (envoltventes) son clases diseadas para complementar los tipos primitivos, los nicos elementos
Java que no son objetos. Presenta ventajas de eficiencia e inconvenientes de funcionalidad. Por ejemplo,
los tipos primitivos siempre se pasan como argumento a los mtodos por valor; los objetos por referencia.
No hay forma de modificar en un mtodo un argumento de tipo primitivo y que se trasmita al entorno que lo
llam. Una forma de conseguirlo es con un Wrapper, un objeto cuya variable miembro es el tipo primitivo a
modificar. Las clases Wrapper tambin proporcionan mtodos para realizar otras tareas con tipos primitivos,
como conversin con cadenas de caracteres en uno y otro sentido.
Existe una clase Wrapper para cada tipo primitivo numrico; existen las clases Byte, Short, Integer, Long,
Float y Double. A continuacin se vern las clases Double e Integer. Las otras cuatro son similares.
La clase java.lang.Double deriva de Number, que deriva de Object. Esta clase contiene un valor primitivo de
tipo double. La tabla muestra algunos mtodos y constantes predefinidas de la clase Double. El Wrapper
Float es similar al Wrapper Double.
Mtodos Funcin
Double(double) y Double(String) Constructores
doubleValue(), floatValue(), longValue(), intValue(), Mtodos para obtener el valor del tipo primitivo
shortValue(), byteValue()
String toString(), Double valueOf(String) Conversores con la clase String
isInfinite(), isNaN() Mtodos de chequeo de condiciones
equals(Object) Compara con otro objeto
MAX_DOUBLE, MIN_DOUBLE, POSITIVE_INFINITY, Constantes predefinidas. TYPE es el objeto Class
NEGATIVE_INFINITY, NaN, TYPE representando esta clase
La clase java.lang.Integer tiene como variable miembro un valor de tipo int. La siguiente tabla muestra los
mtodos y constantes de la clase Integer. Los Wrappers Byte, Short y Long son similares a Integer.
Mtodos Funcin
Integer(int) y Integer(String) Constructores
doubleValue(), floatValue(), longValue(), intValue(), Conversores con otros tipos primitivos
shortValue(), byteValue()
Integer decode(String), Integer parseInt(String), String Conversores con String
toString(), Integer valueOf(String)
String toBinaryString(int), String toHexString(int), Conversores a cadenas representando enteros en
String toOctalString(int) otros sistemas de numeracin
Integer getInteger(String) Determina el valor de una propiedad del sistema a
partir del nombre de dicha propiedad
MAX_VALUE, MIN_VALUE, TYPE Constantes predefinidas
Los Wrappers se usan para convertir cadenas de caracteres (texto) en nmeros. Es til cuando se leen
valores del teclado, de un fichero de texto, etc. Los ejemplos siguientes muestran algunas conversiones:
String numDecimalString = "8.978";
float numFloat=Float.valueOf(numDecimalString).floatValue(); // numFloat = 8,979
double numDouble=Double.valueOf(numDecimalString).doubleValue(); // numDouble = 8,979
String numIntString = "1001";
int numInt=Integer.valueOf(numIntString).intValue(); // numInt = 1001
En caso que el texto no se pueda convertir directamente al tipo especificado se lanza una excepcin de tipo
NumberFormatException, por ejemplo al intentar convertir directamente 4.897 a un nmero entero. El
proceso a seguir ser convertirlo primero a un nmero float y luego a nmero entero.
La clase java.lang.Math deriva de Object. Proporciona mtodos static para operaciones matemticas
habituales y las constantes E y PI. La tabla muestra los mtodos matemticos de la clase.

Programacin en Java 36
Mtodos Significado Mtodos Significado
abs() Valor absoluto sin(double) Seno
acos() Arcocoseno tan(double) Tangente
asin() Arcoseno exp() Funcin exponencial
atan() Arcotangente entre -PI/2 y log() Logaritmo natural (base e)
PI/2
atan2( , ) Arcotangente entre -PI y max( , ) Mximo de dos argumentos
PI
ceil() Entero ms cercano min( , ) Mnimo de dos argumentos
direccin infinito
floor() Entero ms cercano random() N aleatorio entre 0.0 y 1.0
direccin -infinito
er
round() Entero ms cercano al power( , ) 1 argumento elevado al 2
argumento
rint(double) Entero ms prximo sqrt() Raz cuadrada
IEEEremainder(doubl, resto de la divisin toDegrees(double) Pasa de radianes a grados
double)
cos(double) Coseno toRadians() Pasa de grados a radianes
4.4. Colecciones
Java dispone clases e interfaces para trabajar con colecciones de objetos. En primer lugar se vern las
clases Vector y Hashtable, as como la interface Enumeration.
4.4.1. Clase Vector, Hashtable e interface Enumeration
La clase java.util.Vector deriva de Object, implementa Cloneable (para sacar copias con el mtodo clone) y
Serializable (para convertirse en cadena de caracteres). Vector es un array de objetos (referencias a objetos
tipo Object) que puede crecer y reducirse, segn el nmero de elementos. Permite acceder a los elementos
con un ndice, pero no permite usar corchetes.
El mtodo capacity() devuelve el tamao (nmero de elementos) que puede tener el vector; size el que
realmente contiene y capacityIncrement es una variable que indica el salto que se dar en el tamao
cuando haya que crecer. Adems existen otras 2 variables miembro: elementCount, nmero de
componentes vlidos del vector y elementData[], el array de Objects donde realmente se guardan los
elementos del objeto Vector. Las tres variables citadas son protected. La tabla muestra los mtodos
destacados de Vector. Su nmero proporciona gran flexibilidad a la clase.
Mtodos Funcin
Vector(), Vector(int), Vector(int, int) Constructores. Crean un vector vaco de la capacidad
indicada y un vector de capacidad e incremento indicados
void addElement(Object obj) Aade un objeto al final
boolean removeElement(Object obj) Elimina el primer objeto que encuentra como su argumento y
desplaza los restantes. Si no lo encuentra devuelve false
void removeAllElements() Elimina todos los elementos
Object clone() Devuelve una copia del vector
void copyInto(Object anArray[]) Copia un vector en un array
void trimToSize() Ajusta el tamao a los elementos que tiene
void setSize(int newSize) Establece un nuevo tamao
int capacity() Devuelve el tamao (capacidad) del vector
int size() Devuelve el nmero de elementos
boolean isEmpty() Devuelve true si no tiene elementos

Programacin en Java 37
Enumeration elements() Devuelve una Enumeracin con los elementos
boolean contains(Object elem) Indica si contiene o no un objeto
int indexOf(Object elem, int index) Devuelve la posicin de la primera vez que aparece un objeto
a partir de una posicin dada
int lastIndexOf(Object elem, int index) Devuelve la posicin de la ltima vez que aparece un objeto a
partir de una posicin, hacia atrs
Object elementAt(int index) Objeto de una posicin dada
Object firstElement() Primer elemento
Object lastElement() ltimo elemento
void setElementAt(Object obj, int index) Cambia el elemento que est en una posicin dada
void removeElementAt(int index) Elimina el elemento que est en una posicin dada
void insertElementAt(Object obj, int index) Inserta un elemento por delante de una posicin dada
La clase java.util.Hashtable extiende Dictionary (abstract) e implementa Cloneable y Serializable. Una hash
table es una relacin entre clave y un valor (hash). Cualquier objeto distinto de null puede ser clave o valor.
La clase a la que pertenecen las claves debe implementar hashCode y equals para hacer bsquedas y
comparaciones. El mtodo hashCode() devuelve un entero nico y distinto para cada clave, siempre el
mismo en una ejecucin del programa; puede cambiar de una ejecucin a otra. Para 2 claves iguales
(segn equals) hashCode() devuelve el mismo entero(hash). Las hash tables se disean para mantener una
coleccin de pares clave/hash, permitiendo insertar y realizar bsquedas eficientes.
Cada objeto de Hashtable tiene 2 variables: capacity y load factor Hashtable numeros = new Hashtable();
(entre 0.0 y 1.0). Si el nmero de elementos excede su producto,
numbers.put("uno", new Integer(1));
la Hashtable crece llamando al mtodo rehash. Un load factor
ms grande apura la memoria, pero es menos eficiente en numbers.put("dos", new Integer(2));
bsqueda. Conviene partir de una Hashtable adecuada para
evitar ampliaciones. numbers.put("tres", new Integer(3));

El ejemplo define una Hashtable con el mtodo put(). La tabla muestra los mtodos de la clase.
Mtodos Funcin
Hashtable(), Hashtable(int nElements), Hashtable(int Constructores
nElements, float loadFactor)

int size() Tamao de la tabla


boolean isEmpty() Indica si la tabla est vaca
Enumeration keys() Devuelve una Enumeration con las claves
Enumeration elements() Devuelve una Enumeration con los valores
boolean contains(Object value) Indica si hay alguna clave con ese valor
boolean containsKey(Object key) Indica si existe esa clave en la tabla
Object get(Object key) Devuelve un valor dada la clave
void rehash() Ampla la capacidad de la tabla
Object put(Object key, Object value) Establece una relacin clave-valor
Object remove(Object key) Elimina un valor por la clave
void clear() Limpia la tabla
Object clone() Hace una copia de la tabla
String toString() Devuelve un string representando la tabla
La interface java.util.Enumeration define mtodos para recorrer una coleccin de objetos. Puede haber
distintas clases que implementen esta interface, todas con comportamiento similar. Declara 2 mtodos:
1. public boolean hasMoreElements(). Indica si hay ms elementos en la coleccin o si se llega al final

Programacin en Java 38
2. public Object nextElement(). Devuelve el siguiente objeto de la coleccin. Si no hay ms elementos lanza
una NoSuchElementException.
En el cuadro se muestra un ejemplo que for (Enumeration e = vec.elements(); e.hasMoreElements(); ) {
imprime los elementos de un vector vec
System.out.println(e.nextElement());
donde el mtodo elements() devuelve
una referencia de tipo Enumeration. }
Con hasMoreElements() y nextElement() y un bucle for se pueden imprimir los elementos del objeto Vector.
4.4.2. Collections Framework Java 1.2
La versin 1.2 del JDK introdujo Java Framework Collections (JCF), un conjunto de clases e interfaces que
mejoran la capacidad del lenguaje respecto a estructuras de datos. Es el paradigma de aplicacin de los
conceptos de POO. La figura muestra la jerarqua de interfaces JCF.

En letra cursiva se indican las clases que implementan las correspondientes interfaces. Por ejemplo, 2
clases implementan la interface Map: HashMap y Hashtable. Las clases vistas existan antes de JDK 1.2.
Se marcan en la figura con la letra h entre parntesis. Se han mantenido por compatibilidad pero sus
mtodos no siguen las reglas de diseo general de JCF. Se recomienda usar las nuevas clases.
En el diseo de JCF las interfaces son importantes porque determinan la capacidad de las clases que las
implementan. Dos clases que implementan la misma interface se pueden usar en la misma forma, como las
clases ArrayList y LinkedList. La diferencia es la implementacin. ArrayList almacena los objetos en un array
y LinkedList en una lista vinculada. La primera ser ms eficiente para acceder a un elemento arbitrario; la
segunda ser ms flexible para borrar e insertar elementos.
La figura derecha muestra la jerarqua de clases JCF. En fondo blanco se muestran clases abstractas y con
gris quellas de las que se pueden crear objetos. Las clases Collections y Arrays no son abstract, pero no
tienen constructores pblicos con los que se pueden crear objetos. Fundamentalmente contienen mtodos
static para realizar ciertas operaciones de utilidad: ordenar, buscar, introducir ciertas caractersticas en
objetos de otras clases, etc. Los elementos del JCF se pueden estructurar como sigue.
Interfaces de la JCF. Constituyen el elemento central de la JCF.
Collection Define mtodos para tratar una coleccin genrica de elementos
Set Coleccin que no admite elementos repetidos
SortedSet Set cuyos elementos se mantienen ordenados segn criterio
List Admite elementos repetidos y mantiene un orden inicial
Map Conjunto de pares clave/valor, sin repeticin de claves
SortedMap Map cuyos elementos se mantienen ordenados criterio
Interfaces de soporte.
Iterator. Sustituye a Enumeration. Dispone mtodos para recorrer una coleccin y borrar elementos
ListIterator. Deriva de Iterator y permite recorrer lists en ambos sentidos

Programacin en Java 39
Comparable. Declara el mtodo compareTo que permite ordenar colecciones segn un orden
natural (String, Date, Integer, Double)
Comparator. Declara el mtodo compare y se usa en lugar de Comparable cuando se desea
ordenar objetos no estndar o sustituir a dicha interface
Clases de propsito general. Son las implementaciones de las interfaces de la JFC
HashSet Interface Set implementada con una hash table
TreeSet Interface SortedSet implementada con un rbol binario ordenado
ArrayList Interface List implementada con un array
LinkedList Interface List implementada con una lista vinculada
HashMap Interface Map implementada con una hash table
WeakHashMap Interface Map implementada de modo que la memoria de los pares clave/valor
pueda ser liberada cuando las claves no tengan referencia desde el exterior de la WeakHashMap
TreeMap Interface SortedMap implementada con un rbol binario
Clases Wrapper. Colecciones con caractersticas adicionales, como no poder ser modificadas o estar
sincronizadas. No se accede con constructores, sino mediante mtodos factory de la clase Collections
Clases de utilidad. Pequeas implementaciones que permiten obtener sets especializados, como sets
constantes de un slo elemento (singleton) o lists con n copias del mismo elemento (nCopies). Definen las
constantes EMPTY_SET y EMPTY_LIST. Se accede a travs de la clase Collections
Clases histricas. Son las clases Vector y Hashtable de las primeras versiones de Java. En las actuales,
implementan respectivamente las interfaces List y Map, aunque conservan los mtodos anteriores
Clases abstractas. Son las de la figura. Implementan total o parcialmente los mtodos de la interface
correspondiente. Sirven para que los usuarios deriven de ellas sus propias clases con mnimo esfuerzo
Algoritmos. La clase Collections dispone de mtodos static para ordenar, desordenar, invertir orden, realizar
bsquedas, llenar, copiar, hallar el mnimo y hallar el mximo.
Clase Arrays. Es una clase de utilidad introducida en JDK 1.2 que contiene mtodos static para gestionar
los arrays clsicos. Tambin permite tratar los arrays como lists.
4.4.2.1. Interfaces Collection, Iterator y ListIterator
La interface Collection es public interface java.util.Collection
implementada por conjuntos (sets) y
{
listas (lists). Declara mtodos
generales utilizables con Sets y Lists. public abstract boolean add(java.lang.Object); // opcional
La declaracin (header) de los
public abstract boolean addAll(java.util.Collection); // opcional
mtodos se muestra ejecutando el
comando > javap java.util.Collection. public abstract void clear(); // opcional
Su salida es la mostrada.Los mtodos
explican su funcionalidad en su public abstract boolean contains(java.lang.Object);
nombre, los argumentos y su valor de public abstract boolean containsAll(java.util.Collection);
retorno.
public abstract boolean equals(java.lang.Object);
Los mtodos marcados con opcional
pueden no estar disponibles en public abstract int hashCode();
algunas implementaciones, como en public abstract boolean isEmpty();
las clases que no permiten modificar
sus objetos. Estos mtodos deben public abstract java.util.Iterator iterator();
definirse, pero al ser llamados lanzan public abstract boolean remove(java.lang.Object); // opcional
una UnsupportedOperationException.
public abstract boolean removeAll(java.util.Collection); // opcional
El mtodo add trata de aadir un
objeto a una coleccin aunque puede public abstract boolean retainAll(java.util.Collection); // opcional
no conseguirlo porque la coleccin public abstract int size();
sea un set que ya lo contenga. Si
modifica la coleccin devuelve true. Lo public abstract java.lang.Object toArray()[];
mismo con addAll. El mtodo remove public abstract java.lang.Object toArray(java.lang.Object[])[];
elimina un elemento, si lo encuentra y
devuelve true si tiene xito. }

Programacin en Java 40
El mtodo iterator devuelve una referencia Iterator que permite recorrer una coleccin con next y hasNext.
El mtodo remove borra el elemento actual y los 2 mtodos toArray convertir una coleccin en array.
La interface Iterator sustituye a Enumeration de versiones anteriores de JDK. Dispone de los mtodos
mostrados a la izquierda. El mtodo remove permite borrar el ltimo elemento accedido con next. Es la
nica forma segura de eliminar un elemento al recorrer una coleccin.
Compiled from Iterator.java Compiled from ListIterator.java
public interface java.util.Iterator public interface java.util.ListIterator extends java.util.Iterator
{ {
public abstract boolean hasNext(); public abstract void add(java.lang.Object);
public abstract java.lang.Object next(); public abstract boolean hasNext();
public abstract void remove(); public abstract boolean hasPrevious();
} public abstract java.lang.Object next();
Los mtodos de la interface ListIterator son public abstract int nextIndex();
los mostrados a la derecha. Permite recorrer
public abstract java.lang.Object previous();
una lista en ambas direcciones y hacer
modificaciones al recorrerla. Los elementos public abstract int previousIndex();
se numeran desde 0 a n-1 y los valores
public abstract void remove();
vlidos del ndice son de 0 a n.
public abstract void set(java.lang.Object);
El ndice est entre los elementos i-1 e i, de
forma que previousIndex devuelve i-1 y }
nextIndex devolvera i.
Si el ndice es 0, previousIndex devuelve 1 y si es n nextIndex devuelve el resultado de size.
4.4.2.2. Interfaces Comparable y Comparator
Estas interfaces se orientan a ordenar listas, sets y maps. Dispone de las interfaces java.lang.Comparable y
java.util.Comparator (de packages diferentes).
Comparable declara el mtodo compareTo como public int compareTo(Object obj), que compara su
argumento implcito con el que se le pasa por ventana. El mtodo devuelve un entero negativo, cero o
positivo segn el argumento implcito (this) sea anterior, igual o posterior al objeto obj.
Las listas de objetos de clases que implementan esta interface tienen un orden natural. En Java 1.2 esta
interface la implementan, entre otras, las clases String, Character, Date, File, BigDecimal, BigInteger, Byte,
Short, Integer, Long, Float y Double. La implementacin estndar de estas clases no asegura un orden
alfabtico correcto con maysculas y minsculas ni en idiomas distintos al ingls.
Si se redefine el mtodo compareTo debe ser programado con cuidado. Es conveniente que sea coherente
con el mtodo equals y que cumpla la propiedad transitiva. Listas y arrays cuyos elementos implementan
Comparable pueden ser ordenados con los mtodos static Collections.sort() y Arrays.sort().
Comparator permite ordenar listas y colecciones cuyos objetos pertenecen a clases de tipo cualquiera.
Permitira ordenar figuras geomtricas planas por rea o permetro. Su papel es similar al de Comparable,
pero el usuario debe proporcionar su implementacin. Sus dos mtodos se declaran en la forma mostrada.
El objetivo de equals es comparar Comparators y compare public int compare(Object o1, Object o2)
devuelve un entero negativo, 0 o positivo en funcin de que su
public boolean equals(Object obj)
primer argumento sea anterior, igual o posterior al segundo.
Los objetos que implementan Comparator pueden pasarse como argumentos al mtodo Collections.sort o a
algunos constructores de las clases TreeSet y TreeMap, para mantenerlos ordenados de acuerdo con dicho
Comparator. Es importante que compare sea compatible con el equals de los objetos a ordenar. Su
implementacin debe cumplir condiciones similares a las de compareTo. Java 1.2 dispone de clases
capaces de ordenar cadenas de texto en diferentes lenguajes, como se expone en la documentacin de las
clases CollationKey, Collator y sus derivadas del package java.text.
4.4.2.3. Sets y SortedSets
La interface Set permite acceder a una coleccin, ordenada o no, sin elementos repetidos. No declara
mtodos adicionales a los de Collection. Como un Set no admite elementos repetidos hay que saber cundo
2 objetos son considerados iguales (p. ej. las palabras Mesa y mesa sean consideradas iguales). Para ello
se dispone de los mtodos equals y hashcode, que el usuario puede redefinir si lo desea.
Programacin en Java 41
Con los mtodos de Collection los Sets permiten las operaciones algebraicas de unin, interseccin y
diferencia. As, s1.containsAll(s2) permite saber si s2 est contenido en s1.La interface SortedSet extiende
la interface Set y aade los mtodos de la lista.
Se orientan a trabajar con Compiled from SortedSet.java
elementos ordenados.. El
public interface java.util.SortedSet extends java.util.Set
mtodo comparator
permite obtener el objeto {
pasado al constructor para
establecer el orden. Si se public abstract java.util.Comparator comparator();
ha usado el orden natural public abstract java.lang.Object first();
definido por la interface
Comparable, el mtodo public abstract java.util.SortedSet headSet(java.lang.Object);
devuelve null. public abstract java.lang.Object last();
Los mtodos first y last public abstract java.util.SortedSet subSet(java.lang.Object, java.lang.Object);
devuelven el primer y
ltimo elemento del public abstract java.util.SortedSet tailSet(java.lang.Object);
conjunto, respectivamente. }
Los mtodos headSet, subSet y tailSet obtienen subconjuntos al principio, en medio y al final del conjunto
original. Existen 2 implementaciones de conjuntos, la clase HashSet implementa la interface Set y la clase
TreeSet implementa SortedSet. La primera se basa en una hash table y la segunda en un TreeMap.
Los elementos de un HashSet no mantienen el orden natural, ni el de introduccin. Los elementos de un
TreeSet mantienen el orden natural o el especificado por Comparator. Ambas clases definen constructores
que admiten un objeto Collection lo que permite convertir un HashSet en un TreeSet y viceversa.
4.4.2.4. Listas
La interface List define mtodos para operar Compiled from List.java
con colecciones ordenadas que pueden tener
public interface java.util.List extends java.util.Collection
elementos repetidos. Declara mtodos relativos
al orden y acceso a elementos o rangos de los {
mismos. Adems de los mtodos de Collection,
public abstract void add(int, java.lang.Object);
List declara los mtodos mostrados.
Los nuevos mtodos add y addAll tienen un public abstract boolean addAll(int, java.util.Collection);
argumento adicional para insertar elementos en public abstract java.lang.Object get(int);
una posicin dada, desplazando el elemento de
esa posicin y los siguientes. Los mtodos get y public abstract int indexOf(java.lang.Object);
set permiten obtener y cambiar un elemento de public abstract int lastIndexOf(java.lang.Object);
posicin. Los mtodos indexOf y lastIndexOf
permiten saber la posicin de la primera o public abstract java.util.ListIterator listIterator();
ltima vez que un elemento aparece en la lista; public abstract java.util.ListIterator listIterator(int);
si el elemento no se encuentra se devuelve 1.
El mtodo subList(int fromIndex, toIndex) public abstract java.lang.Object remove(int);
devuelve una vista de la lista, desde el public abstract java.lang.Object set(int, java.lang.Object);
elemento fromIndex inclusive hasta toIndex
exclusive. Un cambio en la vista se refleja en la public abstract java.util.List subList(int, int);
lista original, aunque no conviene hacer }
cambios simultneamente en ambas.
Lo aconsejable es eliminar la vista cuando no se necesite. Existen 2 implementaciones de la interface List:
las clases ArrayList y LinkedList. La diferencia estriba en que la primera almacena los elementos de la
coleccin en un array de Objects y la segunda en una lista vinculada. Los arrays proporcionan un acceso a
elementos ms eficiente que las listas, pero tienen dificultades para crecer y para insertar y/o borrar
elementos. Las listas vinculadas slo permiten acceso secuencial, pero presentan gran flexibilidad para
crecer, borrar e insertar elementos. Elegir la opcin adecuada depender del anlisis.
4.4.2.5. Maps y SortedMaps
Un Map es una estructura de datos agrupados en parejas clave/valor (como una tabla de 2 columnas). La
clave debe ser nica y se usa para acceder al valor.
Aunque la interface Map no Compiled from Map.java
deriva de Collection, puede
public interface java.util.Map
entenderse como colecciones de
Programacin en Java 42
parejas clave/valor. Sus mtodos
{
son los mostrados en el cuadro
(comando > javap java.util.Map). public abstract void clear();
El mtodo entrySet() devuelve public abstract boolean containsKey(java.lang.Object);
una vista del Map como Set.
public abstract boolean containsValue(java.lang.Object);
Los elementos del Set son
referencias de la interface public abstract java.util.Set entrySet();
Map.Entry, una interface interna
de Map. public abstract boolean equals(java.lang.Object);

Esta vista del Map como Set public abstract java.lang.Object get(java.lang.Object);
permite modificar y eliminar public abstract int hashCode();
elementos, pero no aadir
nuevos elementos. public abstract boolean isEmpty();

El mtodo get(key) permite public abstract java.util.Set keySet();


obtener el valor a partir de la public abstract java.lang.Object put(java.lang.Object, java.lang.Object);
clave.
public abstract void putAll(java.util.Map);
El mtodo keySet() devuelve una
vista de las claves como Set. public abstract java.lang.Object remove(java.lang.Object);

El mtodo values() devuelve una public abstract int size();


vista de los valores del Map public abstract java.util.Collection values();
como Collection (porque puede
haber elementos repetidos). public static interface java.util.Map.Entry

El mtodo put() permite aadir {


una pareja clave/valor, mientras public abstract boolean equals(java.lang.Object);
que putAll() vuelca todos los
elementos de un Map en otro public abstract java.lang.Object getKey();
Map (los pares con clave nueva public abstract java.lang.Object getValue();
se aaden; en los pares con
clave ya existente los valores public abstract int hashCode();
nuevos sustituyen a los public abstract java.lang.Object setValue(java.lang.Object);
antiguos).
}
El mtodo remove() elimina una
pareja clave/valor a partir de la }
clave.
La interface SortedMap aade los siguientes mtodos, similares a los de SortedSet.
La clase HashMap Compiled from SortedMap.java
implementa la
public interface java.util.SortedMap extends java.util.Map
interface Map y est
basada en una hash {
table, mientras que
public abstract java.util.Comparator comparator();
TreeMap implementa
SortedMap y se basa public abstract java.lang.Object firstKey();
en un rbol binario.
public abstract java.util.SortedMap headMap(java.lang.Object);
public abstract java.lang.Object lastKey();
public abstract java.util.SortedMap subMap(java.lang.Object, java.lang.Object);
public abstract java.util.SortedMap tailMap(java.lang.Object);
}
4.4.2.6. Clases Collections y Arrays
La clase Collections (no Collection) es una clase que define mtodos static con distinta funcionalidad.
Destacan los siguientes.
Mtodos que definen algoritmos
Ordenacin mediante el mtodo mergesort public static void sort(java.util.List);
public static void sort(java.util.List, java.util.Comparator);
Programacin en Java 43
Eliminacin del orden de modo aleatorio public static void shuffle(java.util.List);
public static void shuffle(java.util.List, java.util.Random);
Inversin del orden establecido public static void reverse(java.util.List);
Bsqueda en una lista public static int binarySearch(java.util.List, java.lang.Object);
public static int binarySearch(java.util.List, java.lang.Object, java.util.Comparator);
Copiar una lista o reemplazar todos los elementos con el elemento especificado
public static void copy(java.util.List, java.util.List);
public static void fill(java.util.List, java.lang.Object);
Clculo de mximos y mnimos
public static java.lang.Object max(java.util.Collection);
public static java.lang.Object max(java.util.Collection, java.util.Comparator);
public static java.lang.Object min(java.util.Collection);
public static java.lang.Object min(java.util.Collection, java.util.Comparator);
Mtodos de utilidad
Set inmutable de un nico elemento public static java.util.Set singleton(java.lang.Object);
Lista inmutable con n copias de un objeto public static java.util.List nCopies(int, java.lang.Object);
Constantes para representar el conjunto y la lista vaca
public static final java.util.Set EMPTY_SET;
public static final java.util.List EMPTY_LIST;
La clase Collections dispone de 2 conjuntos de mtodos factory que pueden ser usados para convertir
objetos de distintas colecciones en objetos read only y para convertir distintas colecciones en objetos
synchronized (por defecto las clases anteriores no estn sincronizadas), lo que quiere decir que se puede
acceder a la coleccin desde distintas threads sin problemas. Los mtodos correspondientes son:
public static java.util.Collection synchronizedCollection(java.util.Collection);
public static java.util.List synchronizedList(java.util.List);
public static java.util.Map synchronizedMap(java.util.Map);
public static java.util.Set synchronizedSet(java.util.Set);
public static java.util.SortedMap synchronizedSortedMap(java.util.SortedMap);
public static java.util.SortedSet synchronizedSortedSet(java.util.SortedSet);
public static java.util.Collection unmodifiableCollection(java.util.Collection);
public static java.util.List unmodifiableList(java.util.List);
public static java.util.Map unmodifiableMap(java.util.Map);
public static java.util.Set unmodifiableSet(java.util.Set);
public static java.util.SortedMap unmodifiableSortedMap(java.util.SortedMap);
public static java.util.SortedSet unmodifiableSortedSet(java.util.SortedSet);
Estos mtodos se usan de forma sencilla: se les pasa como argumento una referencia a un objeto que no
cumple la caracterstica deseada y se obtiene como retorno una referencia a un objeto que s la cumple.
4.4.2.7. Clases abstract e interfaces Cloneable y Serializable
Las clases abstract sirven para desarrollar clases propias con funcionalidades no cubiertas por las clases
que provee Java. Las clases HashSet, TreeSet, ArrayList, LinkedList, HashMap y TreeMap (al igual que
Vector y Hashtable) implementan las interfaces Cloneable y Serializable, lo que permite obtener copias bit a
bit de sus objetos con Object.clone y que se pueden convertir en cadenas o flujos (streams) de caracteres.
Una de las ventajas de implementar la interface Serializable es que los objetos de estas clases pueden ser
impresos con los mtodos System.Out.print y System.Out.println.

Programacin en Java 44
4.5. Otras clases del package java.util
El package java.util tiene otras clases para distintas aplicaciones, entre ellas algunas destinadas a lo
relacionado con fechas y horas. Algunas de estas clases se presentan a continuacin.
4.5.1. Clase Date, Calendar y GregorianCalendar
La clase Date representa un instante de Compiled from Date.java
tiempo dado con precisin de ms. La
public class java.util.Date extends java.lang.Object implements
informacin de fecha y hora se guarda
en un entero long (64 bits) que contiene java.io.Serializable, java.lang.Cloneable, java.lang.Comparable {
los ms transcurridos desde las 00:00:00
public java.util.Date();
del 1 ENE 1970 GMT (Greenwich Mean
Time). Otras clases permiten a partir de public java.util.Date(long);
un objeto Date obtener informacin del
ao, mes, da, hora, minuto y segundo. public boolean after(java.util.Date);
En el cuadro se muestran los mtodos public boolean before(java.util.Date);
de la clase Date, sin los mtodos
obsoletos en JDK 1.2. public java.lang.Object clone();

El constructor por defecto Date crea un public int compareTo(java.lang.Object);


objeto a partir de la fecha y hora actual public int compareTo(java.util.Date);
del ordenador y el segundo crea el
objeto a partir de los ms desde el public boolean equals(java.lang.Object);
01/01/1970. Los mtodos after y before public long getTime();
permiten saber si la fecha indicada
como argumento implcito (this) es public int hashCode();
posterior o anterior a la pasada como public void setTime(long);
argumento explcito. Los mtodos
getTime y setTime obtienen o public java.lang.String toString();
establecen los ms desde el 01/01/1970 }
para un determinado objeto Date.
Otros mtodos son consecuencia de las interfaces implementadas por Date. Los objetos de esta clase
suelen usarse, ms que directamente, en combinacin con las clases Calendar y GregorianCalendar. La
clase Calendar es una clase abstract que dispone mtodos para convertir objetos tipo Date en enteros que
representan fechas concretas. La clase GregorianCalendar es la nica clase que deriva de Calendar y es la
usada habitualmente.
Java representa fechas y horas con las siguientes particularidades: las horas se representan con enteros de
0 a 23 (la hora "0" va de las 00:00:00 hasta la 1:00:00) y los minutos y segundos con enteros entre 0 y 59.
Los das del mes se representan con enteros entre 1 y 31, pero los meses con enteros de 0 a 11. Los aos
se representan con enteros de 4 dgitos. Si se representan con 2 dgitos, se resta 1900.
La clase Calendar tiene una serie de variables miembro y constantes (variables final) tiles:
La variable int AM_PM puede tomar 2 valores: las constantes enteras AM y PM
La variable int DAY_OF_WEEK puede tomar los valores int SUNDAY, MONDAY,, SATURDAY.
La variable int MONTH puede tomar los valores int JANUARY, FEBRUARY,, DECEMBER. Para hacer los
programas ms legibles es preferible usar estas constantes simblicas que los nmeros del 0 al 11.
La variable miembro HOUR se usa en los mtodos get y set para indicar la hora de la maana o de la tarde
(de 0 a 11). La variable HOUR_OF_DAY indica la hora del da en formato 24h (de 0 a 23).
Las variables DAY_OF_WEEK, DAY_OF_WEEK_IN_MONTH, DAY_OF_MONTH (o bien DATE),
DAY_OF_YEAR, WEEK_OF_MONTH, WEEK_OF_YEAR tienen un significado evidente. Lo mismo para las
variables ERA, YEAR, MONTH, HOUR, MINUTE, SECOND, MILLISECOND.
Las variables ZONE_OFFSET y DST_OFFSET indican la zona horaria y el desfase en ms respecto a la
zona GMT.
La clase Calendar dispone mtodos para establecer u obtener los distintos valores de la fecha y hora.
Algunos de ellos se muestran en la tabla.
Compiled from Calendar.java public static synchronized java.util.Calendar
getInstance(java.util.TimeZone);
public abstract class java.util.Calendar extends
java.lang.Object implements java.io.Serializable, public static synchronized java.util.Calendar

Programacin en Java 45
java.lang.Cloneable { getInstance(java.util.TimeZone, java.util.Locale);
protected long time; public final java.util.Date getTime();
protected boolean isTimeSet; protected long getTimeInMillis();
protected java.util.Calendar(); public java.util.TimeZone getTimeZone();
protected public final boolean isSet(int);
java.util.Calendar(java.util.TimeZone,java.util.Locale);
public void roll(int, int);
public abstract void add(int, int);
public abstract void roll(int, boolean);
public boolean after(java.lang.Object);
public final void set(int, int);
public boolean before(java.lang.Object);
public final void set(int, int, int);
public final void clear();
public final void set(int, int, int, int, int);
public final void clear(int);
public final void set(int, int, int, int, int, int);
protected abstract void computeTime();
public final void setTime(java.util.Date);
public boolean equals(java.lang.Object);
public void setFirstDayOfWeek(int);
public final int get(int);
protected void setTimeInMillis(long);
public int getFirstDayOfWeek();
public void setTimeZone(java.util.TimeZone);
public static synchronized java.util.Calendar
public java.lang.String toString();
getInstance();
}
public static synchronized java.util.Calendar
getInstance(java.util.Locale);
La clase GregorianCalendar aade las constante BC y AD para la ERA, que representan respectivamente
antes y despus de Jesucristo. Aade varios constructores que admiten como argumentos la informacin de
fecha/hora y, opcionalmente, la zona horaria. En el cuadro se muestra un ejemplo de uso de estas clases.
import java.util.*; System.out.println("Semana del mes:
"+gc.get(Calendar.WEEK_OF_MONTH));
public class PruebaFechas {
System.out.println("Fecha:
public static void main(String arg[]) {
"+gc.get(Calendar.DATE));
Date d = new Date();
System.out.println("Hora:
GregorianCalendar gc = new GregorianCalendar(); "+gc.get(Calendar.HOUR));
gc.setTime(d); System.out.println("Tiempo del dia:
"+gc.get(Calendar.AM_PM));
System.out.println("Era: "+gc.get(Calendar.ERA));
System.out.println("Hora del dia:
System.out.println("Year: "+gc.get(Calendar.YEAR));
"+gc.get(Calendar.HOUR_OF_DAY));
System.out.println("Month: "+gc.get(Calendar.MONTH)); System.out.println("Minuto:
System.out.println("Dia del mes: "+gc.get(Calendar.MINUTE));
"+gc.get(Calendar.DAY_OF_MONTH));
System.out.println("Segundo:
System.out.println("Da de la semana en "+gc.get(Calendar.SECOND));
mes:"+gc.get(Calendar.DAY_OF_WEEK_IN_MONTH));
System.out.println("Dif. horaria:
System.out.println("No de semana: "+gc.get(Calendar.ZONE_OFFSET));
"+gc.get(Calendar.WEEK_OF_YEAR)); }}
4.5.2. Clases DateFormat, SimpleDateFormat, TimeZone y SimpleTimeZone
DateFormat es una clase abstract del import java.util.*;
package java.text, no de java.util. La
import java.text.*;
razn es facilitar lo referente a la
internacionalizacin, un aspecto class SimpleDateForm {
importante de la conversin, que
permite dar formato a fechas y horas public static void main(String arg[]) throws ParseException {
de acuerdo a criterios locales. La SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy
clase dispone de mtodos static para hh:mm:ss");

Programacin en Java 46
convertir Strings representando fechas
SimpleDateFormat sdf2 = new SimpleDateFormat("dd-MM-yy");
y horas en objetos de la clase Date, y
viceversa. Date d = sdf1.parse("12-04-1968 11:23:45");
La clase SimpleDateFormat es la String s = sdf2.format(d);
nica derivada de DateFormat. Es la
System.out.println(s);
que conviene usar. Se usa pasando al
constructor un String definiendo el }
formato a usar, como en el ejemplo
del cuadro. }

La clase TimeZone es tambin una clase abstract para definir la zona horaria. Los mtodos de esta clase
tienen en cuenta el cambio de la hora en verano. La clase SimpleTimeZone deriva de TimeZone. Es la que
conviene usar. El valor por defecto de la zona horaria es el definido en la mquina en que se ejecuta el
programa. Los objetos de esta clase pueden ser usados con los constructores y algunos mtodos de la
clase Calendar para establecer la zona horaria.

Programacin en Java 47
5. EL AWT (ABSTRACT WINDOWS TOOLKIT)
El AWT es la parte de Java dispuesto para la construccin de interfaces grficas de usuario (GUI). Desde la
versin 1.1 de Java, present un cambio notable, en particular en el modelo de eventos. La versin 1.2 ha
incorporado un modelo distinto de componentes llamado Swing.
Para construir una GUI hace falta un contenedor (container), componentes y un modelo de eventos. El
contenedor es la ventana o parte de ella donde se sitan los componentes (botones, barras) y se realizan
los dibujos. Se correspondera con un formulario o una picture box de VB. Los componentes seran los
controles de VB. Y el modelo de eventos se refiere al control del usuario sobre la aplicacin al actuar sobre
los componentes, en general con ratn o teclado.
Cada vez que se realiza una accin, se produce un evento, que el SO transmite al AWT. ste crea un objeto
de una clase de evento, derivada de AWTEvent. El evento es transmitido a un mtodo para que lo gestione.
En VB el entorno de desarrollo crea automticamente el procedimiento que va a gestionar el evento y el
usuario no tiene ms que introducir el cdigo. En Java esto es diferente: el componente u objeto que recibe
el evento debe registrar o indicar previamente qu objeto va a gestionar ese evento.
El modelo de eventos Java se basa en que los objetos sobre los que se producen los eventos (event
sources) registran los objetos que los gestionarn (event listeners). Los mtodos se llamarn
automticamente al producirse el evento. Para garantizar que los event listeners disponen de los mtodos
apropiados para gestionar los eventos se les obliga a implementar una interface Listener dada. As, las
interfaces Listener se corresponden con los tipos de eventos que se pueden producir.
Las capacidades grficas del AWT resultan pobres y complicadas en comparacin con VB, pero pueden ser
ejecutadas casi en cualquier ordenador y con cualquier SO.
El proceso tpicos para construir una aplicacin orientada a eventos sencilla, con GUI empieza identificando
los componentes que constituyen el interface de usuario (botones, mens). Con esto, se crea una clase
para la aplicacin que contenga la funcin main y una clase Ventana, subclase de Frame, que responda al
evento WindowClosing. La funcin main debe crear un objeto de la clase Ventana (en que se introducirn
los componentes identificados) y mostrarlo por pantalla con tamao y posicin correctos.
Al objeto Ventana hay que aadirle los componentes y mens que contenga, bien en el constructor, bien en
el main. Tambin hay que definir los objetos Listener (que responden a los eventos, cuyas clases
implementan las interfaces Listener) para cada evento que deba soportarse. En aplicaciones pequeas, el
propio objeto Ventana puede responder a los eventos de sus componentes. En programas ms grandes se
puede crear uno o ms objetos de clases especiales para ocuparse de los eventos. Finalmente, se deben
implementar los mtodos de las interfaces Listener que vayan a gestionar los eventos.
5.1. Componentes y eventos del AWT Java
Como todas las clases Java, los componentes del AWT pertenecen a una jerarqua de clases; la que
muestra la figura. Todos los componentes derivan de Component, de la que pueden heredar. El package al
que pertenecen estas clases se llama java.awt.

La siguiente figura muestra la jerarqua de clases para los eventos de Java y algunos componentes. Por
conveniencia, estas clases se agrupan en el package java.awt.event.De sus caractersticas destaca que
todos los Components (excepto Window y derivados) deben aadirse a un Container. Un Container puede
ser aadido a otro Container. Para aadir un Component a un Container se usa el mtodo add de Container
(containerName.add(componentName)). Los Containers de mximo nivel son Windows (Frames y Dialogs).
Los Panels y ScrollPanes siempre estn dentro de otro Container. Un Component slo puede estar en un
Container. Si est en un Container y se aade a otro, deja de estar en el primero. La clase Component tiene
una serie de funcionalidades bsicas comunes (variables y mtodos), heredadas por todas sus subclases.

Programacin en Java 48
Todos los eventos en Java 1.2 son
objetos de clases de una jerarqua
de clases dada. La superclase
EventObject pertenece al package
java.util y de ella deriva la clase
AWTEvent, de la que dependen
todos los eventos de AWT.
Los eventos de Java pueden ser
de alto y bajo nivel. Los de alto
nivel tambin se llaman eventos
semnticos, porque la accin de la
que derivan tiene significado en s
misma, en el contexto de las GUI.
Los eventos de bajo nivel son las acciones elementales que hacen posible los eventos de alto nivel.
Son eventos de alto nivel: los 4 que tienen que ver con pulsar botones o elegir comandos en mens
(ActionEvent), cambiar valores en barras de desplazamiento (AdjustmentEvent), elegir valores (ItemEvents)
y cambiar el texto (TextEvent). En la figura, los eventos de alto nivel aparecen en gris. Los de bajo nivel son
los que se producen con operaciones elementales del ratn, teclado, containers y windows.
Las 6 clases de eventos de bajo nivel son los eventos relacionados con componentes (ComponentEvent),
containers (ContainerEvent), con pulsar teclas (KeyEvent), con mover, arrastrar, pulsar y soltar el ratn
(MouseEvent), obtener o perder el focus (FocusEvent) y con las operaciones con ventanas (WindowEvent).
El modelo de eventos se complica cuando se quiere construir un tipo de componente propio, no estndar
del AWT. En ese caso hay que interceptar los eventos de bajo nivel de Java y adecuarlos al problema.
5.1.1. Relacin entre Componentes y Eventos
La siguiente tabla muestra los componentes del AWT y los eventos especficos de cada uno.
Component Eventos Significado
generados
Button ActionEvent Clicar en el botn
Checkbox ItemEvent Seleccionar o deseleccionar un item
CheckboxMenuItem ItemEvent Seleccionar o deseleccionar un item
Choice ItemEvent Seleccionar o deseleccionar un item
Component ComponentEvent Mover, cambiar tamao, mostrar u ocultar un componente
FocusEvent Obtener o perder el focus
KeyEvent Pulsar o soltar una tecla
MouseEvent Pulsar o soltar un botn del ratn; entrar o salir de un
componente; mover o arrastrar el ratn (tiene 2 Listener)
Container ContainerEvent Aadir o eliminar un componente de un container
List ActionEvent Hacer doble click sobre un item de la lista
ItemEvent Seleccionar o deseleccionar un item de la lista
MunuItem ActionEvent Seleccionar un item de un men
Scrollbar AdjustementEvent Cambiar el valor de la scrollbar
TextComponent TextEvent Cambiar el texto
TextField ActionEvent Terminar de editar un texto pulsando Intro
Window WindowEvent Acciones sobre una ventana: abrir, cerrar, iconizar, restablecer e
iniciar el cierre
La relacin entre componentes y eventos indicada en la tabla puede ser confusa si no se tiene en cuenta
que los eventos propios de una superclase de componentes pueden afectar a los componentes de sus
subclases. Por ejemplo, la clase TextArea no tiene eventos especficos o propios, pero puede recibir los de

Programacin en Java 49
su superclase TextComponent. La siguiente tabla muestra los componentes del AWT y los tipos de eventos
que se pueden producir sobre cada uno, teniendo en cuenta tambin los especficos de sus superclases.
Entre ambas tablas se puede inferir qu tipos de eventos estn soportados en Java y qu eventos puede
recibir cada componente del AWT. En la prctica, no todos los tipos de evento tienen el mismo inters.
Eventos que se pueden generar

AWT Components

Adjustement

Component

Container

Window
Mouse
Action

Focus

Item

Text
Key
Button X X X X X
Canvas X X X X
Checkbox X X X X X
Checkbox-MenuItem X
Choice X X X X X
Component X X X X
Container X X X X X
X
Dialog X X X X X
X
Frame X X X X X
Label X X X X
List X X X X X X
MenuItem X
Panel X X X X X
Scrollbar X X X X X
X
TextArea X X X X
X
TextField X X X X X
Window X X X X X X
5.1.2. Interfaces Listener y Clases Adapter
Vistos los eventos que se pueden producir, debe verse cmo gestionarlos segn el modelo Java.
Por un lado, cada objeto que puede recibir un evento (event source), registra uno o ms objetos para que
se gestionen (event listener). Esto se hace con un mtodo donde eventSourceObject es el objeto en el que
se produce el evento y eventListenerObject es que deber gestionar los eventos, en la forma,
eventSourceObject.addEventListener(eventListenerObject).
La relacin entre ambos se establece a travs de una interface Listener que la clase del eventListenerObject
debe implementar. Esta interface proporciona la declaracin de los mtodos que se llamarn cuando se
produzca el evento. La interface a implementar depende del tipo de evento. La siguiente tabla relaciona
tipos de eventos, con la interface a implementar para gestionarlos. Se indican tambin los mtodos
declarados en cada interface.
La correspondencia entre eventos e interfaces Listener es que cada evento tiene su interface, excepto el
ratn que tiene 2: MouseListener y MouseMotionListener. La razn est en los eventos que se producen al
mover el ratn, que se producen con ms frecuencia que las pulsaciones y por eficiencia se gestionan con
la interface MouseMotionListener. El nombre de la interface coincide con el del evento, sustituyendo Event
por Listener. Una vez registrado el objeto que gestionar el evento, que ser de una clase que implemente
la interface Listener adecuada, se deben definir los mtodos de dicha interface. Siempre hay que definir los
mtodos de la interface, aunque algunos puedan estar vacos. Un ejemplo es la implementacin de la
interface WindowListener vista, en el que todos los mtodos estaban vacos excepto windowClosing.

Programacin en Java 50
Evento Interface Listener Mtodos Listener
ActionEvent ActionListener actionPerformed()

AdjustementEvent AdjustementListener adjustementValueChanged()


ComponentEvent ComponentListener componentHidden(), componentMoved(),
componentResized(),componentShown()
ContainerEvent ContainerListener componentAdded(), componentRemoved()
FocusEvent FocusListener focusGained(), focusLost()
ItemEvent ItemListener itemStateChanged()
KeyEvent KeyListener keyPressed(), keyReleased(), keyTyped()
MouseEvent MouseListener mouseClicked(), mouseEntered(), mouseExited(),
mousePressed(), mouseReleased()
mouseDragged(), mouseMoved()
MouseMotionListener
TextEvent TextListener textValueChanged()
WindowEvent WindowListener windowActivated(), windowDeactivated(), windowClosed(),
windowClosing(), windowIconified(), windowDeiconified(),
windowOpened()
Java ofrece ayudas para definir los mtodos declarados en las interfaces Listener. Por ejemplo, las clases
Adapter, que existen para cada interface Listener con ms de un mtodo. Su nombre se construye a partir
del nombre de la interface, sustituyendo Listener por Adapter. Hay 7 clases Adapter: ComponentAdapter,
ContainerAdapter, FocusAdapter, KeyAdapter, MouseAdapter, MouseMotionAdapter y WindowAdapter.
La clase Adapter derivan de Object. Son clases // Fichero VentanaCerrable2.java
predefinidas que contienen definiciones vacas
import java.awt.*; import java.awt.event.*;
de los mtodos de la interface. Para crear un
objeto que responda al evento, en vez de crear class VentanaCerrable2 extends Frame {
una clase que implemente Listener, se crea una
public VentanaCerrable2() { super(); } // constructores
clase que derive del Adapter correspondiente y
redefina slo los mtodos de inters. P. ej. la public VentanaCerrable2(String title) {
clase VentanaCerrable vista, se poda haber
definido como en el cuadro. super(title);

Las sentencias que definen la clase auxiliar setSize(500,500);


(helper class) derivada de WindowAdapter CerrarVentana cv = new CerrarVentana();
indican que hereda la definicin de los mtodos
de la interface WindowListener. Lo que hay que this.addWindowListener(cv);
hacer es redefinir el nico mtodo necesario }
para cerrar ventanas. El constructor de la clase
VentanaCerrable crea un objeto de clase } // Fin de la clase VentanaCerrable2
CerrarVentana y lo registra como event listener class CerrarVentana extends WindowAdapter {
en la sentencia (this.addWindowListener). La
palabra this es opcional. Si no se incluye, se void windowClosing(WindowEvent we) { System.exit(0); }
supone que el event source es el objeto de la } // fin de la clase CerrarVentana
clase en que se produce el evento: la ventana.
Otra forma de responder al evento que se produce cuando el usuario desea cerrar la ventana es usar clases
annimas. Para gestionar eventos slo hace falta un objeto registrado como event listener con los mtodos
adecuados de Listener.
Las clases annimas son tiles si slo se necesita un // Fichero VentanaCerrable3.java
objeto de la clase: este caso. La nueva definicin de la
import java.awt.*; import java.awt.event.*;
clase VentanaCerrable podra ser la mostrada en el
cuadro. El objeto event listener se crea justo al pasarlo class VentanaCerrable3 extends Frame {
como argumento al mtodo addWindowListener. Se
crea un nuevo objeto porque aparece new. public VentanaCerrable3() { super(); }
public VentanaCerrable3(String title) {
Debe tenerse en cuenta que no se crea un nuevo objeto

Programacin en Java 51
de WindowAdapter (clase abstract), sino que se
super(title);
extiende WindowAdapter, aunque extends no
aparezca. Esto lo indican las llaves que se abren tras setSize(500,500);
new WindowAdapter().
this.addWindowListener(new WindowAdapter() {
Los parntesis podran contener argumentos para el
public void windowClosing() {System.exit(0);}
constructor de WindowAdapter, en caso que los
necesitase. En la siguiente sentencia se redefine el });
mtodo windowClosing. En la siguiente lnea se cierran
las llaves de la clase annima y el parntesis del }
mtodo addWindowListener. } // fin de la clase VentanaCerrable
5.2. Clase Component
La clase Component es una clase abstract de la que derivan las clases del AWT. Los mtodos de esta clase
se conocen como componentes grficos o componentes que permiten construir GUI y generar eventos. Son
heredados por todos los componentes del AWT. La tabla muestra algunos de sus mtodos caractersticos.
Mtodos de Component Funcin
boolean isVisible(), void setVisible(boolean) Chequean o establecen visibilidad a un componente
Indican si un componente se est viendo. Debe ser
boolean isShowing()
visible y su container estar mostrndose
Permiten saber si un componente est activado y
boolean isEnabled(), void setEnabled(boolean)
activarlo o desactivarlo
Point getLocation(), Point getLocationOnScreen() Obtienen la posicin de la esquina superior izqda..
de un componente respecto al padre o la pantalla
Desplazan un componente a la posicin dada
void setLocation(Point), void setLocation(int x, int y)
respecto al container o componente-padre
Dimension getSize(), void setSize(int w, int h), void Obtienen o establecen el tamao de un componente
setSize(Dimension d)
void setBounds(int x, int y, int width, int height), void Obtienen o establecen la posicin y el tamao de un
setBounds(Rectangle), Rectangle getBounds() componente
Invalidate marca un componente y contenedores
invalidate(), validate(), doLayout()
indicando que hay que volver a aplicar Layout
Manager; validate asegura que est bien aplicado y
doLayout hace que se aplique
paint(Graphics), repaint() y update(Graphics) Mtodos grficos para dibujar en la pantalla
setBackground(Color), setForeground(Color) Mtodos para establecer los colores por defecto
En las declaraciones de los mtodos de la clase aparecen las clases Point, Dimension y Rectangle. La clase
java.awt.Point tiene 2 variables miembro int; x e y. Dimension tiene 2 variables miembro int; height y width.
Rectangle 4 variables int (height, width, x e y). Las 3 son subclases de Object. Adems de los mtodos de la
tabla, la clase Component tiene otros muchos. Entre otras, permiten controlar colores, fuentes y cursores.
5.2.1. Clase Container
La tabla muestra algunos de los mtodos de la clase container.
Mtodos de Container Funcin
Component add(Component) Aade un componente al container
doLayout() Ejecuta el algoritmo de ordenacin del layout manager
Component getComponent(int) Obtiene el n-simo componente en el container
Component getComponentAt(int, int), Component Obtiene el componente con un determinado punto
getComponentAt(Point)
int getComponentCount() Obtiene el nmero de componentes en el container
Component[] getComponents() Obtiene los componentes en este container
remove(Component), remove(int), removeAll() Elimina el componente especificado
setLayout(LayoutManager) Determina el layout manager para este container

Programacin en Java 52
La clase Container es una clase muy general. No suele instarciar objetos. Sus mtodos son heredados por
Frame y Panel, que s instancian objetos con mucha frecuencia. Los containers mantienen la lista de objetos
que se les va aadiendo. Cuando se aade uno se incorpora al final de la lista, salvo que se especifique una
posicin dada. Tiene mucha importancia lo relacionado con los Layout Managersms adelante.
5.2.1.1. Clase Panel y ScrollPane
Un Panel es un Container de propsito general. Se puede usar para contener otros componentes o para
crear una subclase para alguna finalidad ms especfica. Por defecto, el Layout Manager de Panel es
FlowLayout. Los Applets son subclases de Panel. La tabla muestra los mtodos ms importantes usados
con Panel, algunos heredados de Componet y Container, Panel no tiene mtodos propios.
Mtodos de Panel Funcin
Panel(), Panel(LayoutManager miLM) Constructores de Panel
Mtodos heredados de Container y Component Funcin
add(Component), add(Component, int) Aade componentes al panel
setLayout(), getLayout() Establece o permite obtener el layout manager usado
validate(), doLayout() Para reorganizar los componentes despus de algn
cambio. Es mejor utilizar validate
remove(int), remove(Component), removeAll() Eliminan componentes
Dimension getMaximumSize(), Dimension Permite obtener los tamaos mximo, mnimo y
getMinimumSize(), Dimension getPreferredSize() preferido
Insets getInsets()
Un Panel puede contener otros Panel. Es una ventaja respecto a otros containers, que al ser de mximo
nivel no lo permiten. Insets es una clase que deriva de Object. Sus variables son top, left, botton, right.
Representa el espacio libre en los bordes de un Container. Se establece llamando al constructor adecuado
del Layout Manager.
Por su parte, un ScrollPane es una especie de ventana de tamao limitado en la que se puede mostrar un
componente de mayor tamao con dos Scrollbars, una horizontal y otra vertical. El componente puede ser,
por ejemplo, una imagen. Las Scrollbars son visibles slo si son necesarias (por defecto). Las constantes de
ScrollPane son SCROLLBARS_AS_NEEDED, SCROLLBARS_ALWAYS, SCROLLBARS_NEVER. Los
ScrollPanes no generan eventos. La tabla muestra algunos mtodos de esta clase. En caso en que no
aparezcan scrollbars (SCROLLBARS_NEVER) ser necesario desplazar el componente (hacer scrolling)
desde programa, con el mtodo setScrollPosition.
Mtodos de ScrollPane Funcin
ScrollPane(), ScrollPane(int scbs) Constructores que pueden incluir las ctes.
Dimension getViewportSize(), int Obtiene el tamao del ScrollPane y la altura y anchura
getHScrollbarHeight(), int getVScrollbarWidth() de las barras de desplazamiento
setScrollPosition(int x, int y), setScrollPosition(Point Permiten establecer u obtener la posicin del
p), Point getScrollPosition() componente
setSize(int, int), add(Component) Heredados de Container, permiten establecer el
tamao y aadir un componente
5.2.1.2. Clase Window, Frame, Dialog y FileDialog
Los objetos de la clase Window son ventanas de mximo nivel, sin bordes ni barra de mens. Interesan ms
sus derivadas, Frame y Dialog. Los mtodos ms tiles, se muestran en la tabla.
Mtodos de Window Funcin
toFront(), toBack() Para desplazar la ventana hacie adelante y hacia atrs en la pantalla
show() Muestra la ventana y la trae a primer plano
pack() Hace que los componentes se reajusten al tamao preferido
La clase Frame es una ventana con borde que puede tener barra de mens. Si una ventana depende de
otra es mejor usar una Window a Frame. La tabla muestra mtodos comunes de la clase Frame. Adems de
los mtodos citados, se usan mucho show, pack, toFront y toBack, heredados de Window.

Programacin en Java 53
Mtodos de Frame Funcin
Frame(), Frame(String title) Constructores
String getTitle(), setTitle(String) Obtienen o determinan el ttulo de la ventana
MenuBar getMenuBar(), setMenuBar(MenuBar), Permite obtener, establecer o eliminar la barra de
remove(MenuComponent) mens
Image getIconImage(), setIconImage(Image) Obtienen o determinan el icono que aparecer en la
barra de ttulos
setResizable(boolean), boolean isResizable() Determinan o chequean si se puede cambiar el tamao
dispose() Libera los recursos de una ventana. Todos los
componentes de la ventana son destruidos
La clase Dialog implementa ventanas que dependen de otras (un Frame). Si una Frame se cierra, se cierran
sus Dialog; si se iconifica, desaparecen; si se restablece, aparecen de nuevo. Este comportamiento es
automtico. Los Applets estndar no soportan Dialogs porque no son Frames de Java. Los Applets que
abren Frames s soportan Dialogs. Un Dialog modal require la atencin inmediata del usuario: no se puede
hacer nada hasta cerrarlo. Por defecto, los Dialogs son no modales. La tabla muestra los mtodos ms
importantes de Dialog.
Mtodos de Dialog Funcin
Dialog(Frame fr), Dialog(Frame fr, boolean mod), Constructores
Dialog(Frame fr, String title), Dialog(Frame fr, String
title, boolean mod)
String getTitle(), setTitle(String) Permite obtener o determinar el ttulo
boolean isModal(), setModal(boolean) Pregunta o determina si el Dialog es modal o no
boolean isResizable(), setResizable(boolean) Pregunta o determina si puede cambiar el tamao
show() Muestra y trae a primer plano el Dialog
La clase FileDialog deriva de Dialog y muestra un dilogo para seleccionar un fichero. Las constantes
enteras LOAD (abrir ficheros para lectura) y SAVE (abrir ficheros para escritura) definen el modo de
apertura del fichero. La tabla muestra mtodos de la clase. La interface java.io.FilenameFilter a las clases
que la implementan les permite filtrar ficheros de un directorio.
Mtodos de FileDialog Funcin
FileDialog(Frame parent), FileDialog(Frame parent, String Constructores
title), public FileDialog(Frame parent, String title, int mode)
int getMode(),setMode(int mode) Modo de apertura (SAVE o LOAD)
String getDirectory(), String getFile() Obtiene el directorio o fichero elegido
setDirectory(String dir), setFile(String file) Determina el directorio o fichero elegido
FilenameFilter getFilenameFilter(), Determina o establece el filtro para los
setFilenameFilter(FilenameFilter filter) ficheros
5.2.2. Clases Button, Canvas, Checkbox y CheckboxGroup
Un Button de clase Button puede recibir seis tipos de eventos de clase ActionEvent, generados al hacer clic.
El aspecto de un Button depende de la plataforma, pero la funcionalidad es la misma. Se puede cambiar el
texto, fuente, foreground y backgroung color y establecer que est activo o no.
Mtodos de Button Funcin
Button(String label) y Button() Constructores
setLabel(String str), String getLabel() Permite establecer u obtener la etiqueta del Button
addActionListener(ActionListener al), Permite registrar el objeto que gestionar los eventos, que
removeActionListener(ActionListener al) debe implementar ActionListener
setActionCommand(String cmd), String Establece y recupera un nombre para el objeto Button
getActionCommand() independiente del label y del idioma

Programacin en Java 54
Un Canvas es una zona rectangular de pantalla en la que dibujar y que puede generar eventos. Las Canvas
permiten realizar dibujos, mostrar imgenes y crear componentes a medida, de modo que muestren un
aspecto similar en todas las plataformas. La tabla muestra los mtodos de la clase Canvas.
Desde los objetos de Canvas se puede llamar a los mtodos paint y repaint de Component. Con frecuencia
conviene redefinir los mtodos de Component getPreferredSize, getMinimumSize y getMaximumSize, que
devuelven un objeto de clase Dimension. El LayoutManager utiliza estos valores. La clase Canvas no tiene
eventos propios, pero puede recibir los ComponentEvent de su superclase Component.
Mtodos de Canvas Funcin
Canvas() El nico constructor de la clase
paint(Graphics g); Dibuja un rectngulo con el color de background. Lo normal es que las
subclases redefinan el mtodo
Los objetos de la clase Checkbox son botones de opcin o seleccin con 2 posibles valores: on y off. Al
cambiar la seleccin de un Checkbox se produce un ItemEvent. La clase CheckboxGroup permite la opcin
de agrupar Checkbox de modo que slo uno est en on (al comienzo pueden estar todos off). Se
corresponde con los botones de opcin de VB. La tabla muestra los mtodos ms importantes.
Mtodos de Checkbox Funcin
Checkbox(), Checkbox(String), Checkbox(String, Constructores. Algunos permiten establecer la
boolean), Checkbox(String, boolean, CheckboxGroup), etiqueta, si est o no seleccionado y si pertenece
Checkbox(String, CheckboxGroup, boolean) a un grupo
addItemListener(ItemListener), Registra o elimina los objetos que gestionarn los
removeItemListener(ItemListener) eventos ItemEvent
setLabel(String), String getLabel() Establece u obtiene la etiqueta del componente
setState(boolean), boolean getState() Establece u obtiene el estado (true / false) segn
est seleccionado o no
setCheckboxGroup(CheckboxGroup), CheckboxGroup Establece u obtiene el grupo al que pertenece el
getCheckboxGroup() Checkbox
Mtodos de CheckboxGroup Funcin
CheckboxGroup() Constructores de CheckboxGroup
Checkbox getSelectedCheckbox(), Obtiene o establece el componente seleccionado
setSelectedCheckbox(Checkbox box) de un grupo
Cuando el usuario acta sobre un objeto Checkbox se ejecuta el mtodo itemStateChanged(), nico mtodo
de la interface ItemListener. Si hay varias checkboxes cuyos eventos se gestionan en un mismo objeto y se
quiere saber el que recibe el evento, se puede usar el mtodo getSource del evento EventObject.
Tambin se puede usar el mtodo getItem de ItemEvent, cuyo valor de retorno es un Object con el label del
componente (para convertirlo a String habra que hacer cast). Para crear un grupo o conjunto de botones de
opcin (slo uno podr estar activo), se debe crear un objeto de clase CheckboxGroup. Este objeto no tiene
datos, slo sirve de identificador. Cuando se crean los objetos Checkbox se pasa a los constructores el
objeto CheckboxGroup del grupo al que pertenecern. Cuando se selecciona un Checkbox de un grupo se
producen 2 eventos: uno por el elemento seleccionado y otro por haber perdido la seleccin el elemento
seleccionado anteriormente.
5.2.3. Clases Choice, Label, List y Scrollbar
La clase Choice permite elegir un item de una lista desplegable. Los objetos Choice ocupan menos espacio
en pantalla que los Checkbox. Al elegir un item se genera un evento ItemEvent. Un index permite
determinar un elemento de la lista (empezando en 0). La tabla muestra algunos mtodos de la clase. En
este sentido es similar a las clases Checkbox y CheckboxGroup, as como a los mens de seleccin.
La clase Label introduce en un container un texto no seleccionable ni editable, que por defecto se alinea por
la izquierda. Define las constantes Label.CENTER, Label.LEFT y Label.RIGHT para alinear el texto. La
eleccin de la fuente, colores, tamao y posicin se realiza con los mtodos heredados de Component y no
tiene ms eventos que los de Component.
La clase List define una zona de pantalla con varias lneas, de las que se muestran slo algunas y de las
que se puede hacer una seleccin simple o mltiple. Las List generan eventos de la clase ActionEvents (al
pulsar 2 veces un item o return) e ItemEvents (al seleccionar o deseleccionar un item). Al gestionar el

Programacin en Java 55
evento ItemEvent se puede preguntar si el usuario estaba pulsando a la vez alguna tecla (Alt, Ctrl, Shift).
List se diferencia de Choices en que muestra varios items a la vez y permite hacer seleccin mltiples.
Mtodos de Choice Funcin
Choice() Constructor
addItemListener(ItemListener), Establece o elimina un ItemListener
removeItemListener(ItemListener)
add(String), addItem(String) Aade un elemento a la lista
insert(String label, int index) Inserta un elemento con un label en la posicin
indicada
int getSelectedIndex(), String getSelectedItem() Obtiene el index o label del elemento de la lista
int getItemCount() Obtiene el nmero de elementos
String getItem(int) Obtiene el label a partir del index
select(int), select(String) Selecciona un elemento por el index o el label
removeAll(), remove(int), remove(String) Elimina todos o uno de los elementos de la lista
Mtodos de Label Funcin
Label(String lbl), Label(String lbl, int align) Constructores
setAlignement(int align), int getAlignement() Establecer u obtener la alineacin del texto
setText(String txt), String getText() Establecer u obtener el texto del Label
Mtodos de List Funcin
List(), List(int nl), List(int nl, boolean mult) Constructor: por defecto una lnea y seleccin simple
add(String), add(String, int), addItem(String), Aadir un item. Por defecto al final
addItem(String, int)
addActionListener(ActionListener), Registra los objetos que gestionarn los dos tipos de
addItemListener(ItemListener) eventos soportados
insert(String, int) Inserta un nuevo elemento en la lista
replaceItem(String, int) Sustituye el item en posicin int por el String
delItem(int), remove(int), remove(String), removeAll() Eliminar uno o todos los items de la lista
int getItemCount(), int getRows() Obtener el nmero de items o el nmero de items
visibles
String getItem(int), String[] getItems() Obtiene uno o todos los elementos de la lista
int getSelectedIndex(), String getSelectedItem(), int[] Obtiene el/los elementos seleccionados
getSelectedIndexes(), String[] getSelectedItems()
select(int), deselect(int) Selecciona o elimina la seleccin de un elemento
boolean isIndexSelected(int), Boolean Indica si un elemento est seleccionado o no
isItemSelected(String)
boolean isMultipleMode(), setMultipleMode(boolean) Pregunta o establece modo de seleccin mltiple
int getVisibleIndex(), makeVisible(int) Indicar o establecer si un item es visible
Un Scrollbar es una barra de desplazamiento con cursor que permite introducir y modificar valores, entre un
valor mnimo y mximo, con pequeos y grandes incrementos. Las Scrollbars de Java se usan tanto como
sliders o barras de desplazamiento aisladas (al estilo de VB), como unidas a una ventana en posicin
vertical y/u horizontal para mostrar una cantidad de informacin superior a la que cabe en la ventana.
La clase Scrollbar tiene dos constantes, Scrollbar.HORIZONTAL y Scrollbar.VERTICAL, que indican la
posicin de la barra. Cambiar el valor del Scrollbar genera un AdjustementEvent. En el constructor general,
el parmetro pos es la constante que indica la posicin de la barra (horizontal o vertical); el rango es el
intervalo entre los valores mnimo min y mximo max; el parmetro vis (visibleAmount) el tamao del rea
visible en el caso en que las Scrollbars se usen en TextAreas.

Programacin en Java 56
En ese caso, el tamao del cursor representa la relacin entre el rea visible y el rango, como es habitual en
aplicaciones WS. El valor seleccionado lo da la variable value. Cuando es igual a min el rea visible
comprende el inicio del rango; cuando es max el rea visble comprende el final del rango. Cuando la
Scrollbar se va a usar aislada (como slider), se debe anular visibleAmount.
Las variables Unit Increment y Block Increment representan, respectivamente, los incrementos pequeo y
grande. Por defecto, Unit Increment es 1 y Block Increment 10, mientras que min es 0 y max 100. Al
cambiar el valor de una Scrollbar se genera un evento AdjustementEvent y se ejecuta el nico mtodo de la
interface AdjustmentListener, que es adjustmentValueChanged.
Mtodos de Scrollbar Funcin
Scrollbar(), Scrollbar(int pos), Scrollbar(int pos, int val, int Constructores
vis, int min, int max)
addAdjustmentListener(AdjustmentListener) Registra el objeto que gestionar los eventos
int getValue(), setValue(int) Permiten obtener y fijar el valor
setMaximum(int), setMinimum(int) Establecen los valores mximo y mnimo
setVisibleAmount(int), int getVisibleAmount() Establecen y obtienen el tamao del rea visble
setUnitIncrement(int), int getUnitIncrement() Establecen y obtienen el incremento pequeo
setBlockIncrement(int), int getBlockIncrement() Establecen y obtienen el incremento grande
setOrientation(int), int getOrientation() Establecen y obtienen la orientacin
setValues(int value, int vis, int min, int max) Establecen los parmetros de la barra
5.2.4. Clases TextComponent, TextArea y TextField
La clase TextComponent es general y deriva en las clasesTextArea y TextField, que muestran texto editable
y seleccionable. Su diferencia es que TextField slo puede tener una lnea y TextArea varias. Adems,
TextArea ofrece posibilidades de edicin de texto adicionales (fuente, color de foreground y background).
Slo la clase TextField genera ActionEvents, pero al heredar ambas de TextComponent ambas pueden
recibir TextEvents. La tabla muestra algunos mtodos de las clases TextComponent, TextField y TextArea.
No se pueden crear objetos de la clase TextComponent porque su constructor no es public.
Mtodos heredados de TextComponent Funcin
String getText() y setText(String str) Permiten establecer u obtener el texto del componente
setEditable(boolean b), boolean isEditable() Hace que el texto sea editable o pregunta por ello
setCaretPosition(int n), int getCaretPosition() Fija la posicin del punto de insercin o la obtiene
String getSelectedText(), int getSelectionStart(), Obtiene texto seleccionado, inicio y final de la seleccin
int getSelectionEnd()
selectAll(), select(int start, int end) Selecciona todo o parte del texto
Mtodos de TextField Funcin
TextField(), TextField(int ncol), TextField(String Constructores
s), TextField(String s, int ncol)
int getColumns(), setColoumns(int) Obtiene o establece el n de columnas del TextField
setEchoChar(char c), char getEchoChar(), Establece, obtiene o pregunta por el carcter usado para
boolean echoCharIsSet() passwords, para que no se pueda leer lo tecleado
Mtodos de TextArea Funcin
TextArea(), TextArea(int nfil, int ncol), Constructores
TextArea(String text), TextArea(String text, int
nfil, int ncol)
setRows(int), setColumns(int), int getRows(), int Establece u obtiene el n de filas y columnas
getColumns()
append(String str), insert(String str, int pos), Aadir texto al final, insertarlo en una posicin
replaceRange(String s, int i, int f) determinada y reemplazar un texto determinado

Programacin en Java 57
TextComponent recibe eventos TextEvent, por lo que tambin los reciben sus clases derivadas. Este evento
se produce al modificar el texto del componente. TextField soporta tambin el evento ActionEvent,
producido al terminar de editar la nica lnea de texto pulsando Intro. Las cajas de texto pueden recibir
tambin los eventos de sus superclases, en concreto los de Component Focus, Mouse y KeyEvent.
Estos permiten capturar las teclas pulsadas por el usuario y tomar accin. Por ejemplo, si el usuario debe
teclear un nmero en un TextField, se puede crear una funcin que vaya capturando las pulsaciones y
rechace las no numricas. Cuando se cambia desde programa el nmero de filas y columnas de un
TextField o TextArea, hay que llamar al mtodo validate de Component, para que vuelva a aplicar el
LayoutManager correspondiente. Los tamaos fijados por el usuario tienen carcter de recomendaciones o
tamaos preferidos, que el LayoutManager puede cambiar si es necesario.
5.3. Clases EventObject y AWTEvent
Los mtodos de las interfaces Listener relacionados con el AWT tienen como argumento nico un objeto de
alguna clase derivada de java.awt.AWTEvent. La clase AWTEvent deriva de java.util.EventObject.
La clase AWTEvent no define mtodos, pero hereda de EventObject el mtodo getSource que devuelve una
referencia al objeto que gener el evento. Las clases de eventos que descienden de AWTEvent definen
mtodos similares a getSource con valores de retorno menos genricos. As, la clase ComponentEvent
define el mtodo getComponent, cuyo valor de retorno es un objeto de la clase Component.
5.3.1. Clases ActionEvent, Adjustment Event, ItemEvent y TextEvent
La clase ActionEvent engloba los eventos ActionEvent originados al pulsar con el ratn en un botn, elegir
un comando de un men, hacer doble clic en un elemento de una lista y al pulsar Intro al introducir texto en
una caja de texto (Button, MenuItem, List, TextField). El mtodo String getActionCommand devuelve el texto
asociado a la accin que provoc el evento.
El texto se puede fijar con el mtodo setActionCommand(String str) de las clases Button y MenuItem. Si no
se hace, el mtodo getActionCommand devuelve el texto mostrado por el componente (etiqueta). Para
objetos con varios items el valor devuelto es el nombre del item seleccionado.
El mtodo getModifiers devuelve un entero representando una constante definida en ActionEvent
(SHIFT_MASK, CTRL_MASK, META_MASK y ALT_MASK). Estas constantes determinan si se puls una
de estas teclas al hacer clic. P. ej., si se estaba pulsando la tecla CTRL la siguiente expresin no es 0:
actionEvent.getModifiers() & ActionEvent.CTRL_MASK.
La clase AdjustmentEvent gestiona eventos AdjustementEvent, los generados al cambiar el valor (entero)
de un Scrollbar. Hay 5 tipos de AdjustementEvent: track (arrastrar el cursor del Scrollbar); unit increment,
unit decrement (clic en las flechas del Scrollbar) y block increment, block decrement (clic encima o debajo
del cursor). La tabla muestra algunos mtodos de la clase. Las constantes UNIT_INCREMENT,
UNIT_DECREMENT, BLOCK_INCREMENT, BLOCK_DECREMENT, TRACK permiten saber el tipo de
accin producida, comparando con el valor de retorno de getAdjustementType.
Mtodos de AdjustementEvent Funcin
Adjustable getAdjustable() Devuelve el Component que gener el evento (implementa Adjustable)
int getAdjustementType() Devuelve el tipo de adjustement
int getValue() Devuelve el valor de la Scrollbar despus del cambio
La clase ItemEvent engloba los ItemEvent. Se dan si ciertos componentes (Checkbox, CheckboxMenuItem,
Choice y List) cambian de estado (on/off). Estos componentes implementan la interface ItemSelectable. La
clase ItemEvent define las constantes enteras SELECTED y DESELECTED, que se pueden usar para
comparar con el valor devuelto por el mtodo getStateChange.
Mtodos de ItemEvent Funcin
Object getItem() Devuelve el objeto donde se origin el evento
ItemSelectable getItemSelectable() Devuelve el objeto ItemSelectable donde se origin el evento
int getStateChange() Devuelve la constante SELECTED o DESELECTED de ItemEvent
La clase TextEvent. Se produce un TextEvent cada vez que cambia algo en un TextComponent (TextArea y
TextField). Si se desea evitar ciertos caracteres hay que gestionar los eventos correspondientes. La
interface TextListener tiene un nico mtodo: void textValueChanged(TextEvent te). No hay mtodos
propios de TextEvent. Se puede usar el mtodo Object getSource, heredado de EventObject.

Programacin en Java 58
5.3.2. Clase ComponentEvent
Los eventos ComponentEvent se generan cuando un Component de cualquier tipo se muestra, oculta o
cambia de posicin o tamao. Los eventos mostrar u ocultar ocurren al llamar al mtodo setVisible(boolean)
del Component, pero no cuando se minimiza la ventana. Otro mtodo til de la clase es Component
getComponent que devuelve el componente que gener el evento. Puede usarse como getSource.
5.3.2.1. Clases ContainerEvent, FocusEvent y WindowEvent
Clase ContainerEvent. Los ContainerEvents se generan cuando un Component se aade o elimina de un
Container. Slo tienen un papel de aviso; no es necesario gestionarlos para realizar la operacin. Los
mtodos de esta clase son Component getChild, que devuelve el Component aadido o eliminado y
Container getContainer, que devuelve el Container que gener el evento.
Clase FocusEvent. El Focus est relacionado con la posibilidad de sustituir al ratn por el teclado en ciertas
operaciones. De los componentes que aparecen en pantalla, en un momento dado slo uno puede recibir
acciones del teclado; el que tiene el Focus. ste aparece diferente de los dems y el Focus se cambia con
la tecla Tab o el ratn. Se produce un FocusEvent cada vez que un componente gana o pierde el Focus. El
mtodo requestFocus de Component permite hacer desde programa que un componente obtenga el Focus.
El mtodo boolean isTemporary, de FocusEvent, indica si la prdida del Focus es o no temporal. El mtodo
Component getComponent es heredado de ComponentEvent, y permite conocer el componente que ha
ganado o perdido el Focus. Las constantes de esta clase FOCUS_GAINED y FOCUS_LOST permiten saber
el tipo de evento FocusEvent producido.
Clase WindowEvent. Se produce un WindowEvent al abrir, cerrar, iconizar, restaurar, activar o desactivar
una ventana. La interface WindowListener ofrece los 7 mtodos siguientes, con los que responder al evento:
Mtodos de WindowsListener Funcin
void windowOpened(WindowEvent we); antes de mostrarla por primera vez
void windowClosing(WindowEvent we); al recibir una solicitud de cierre
void windowClosed(WindowEvent we); despus de cerrar la ventana
void windowIconified(WindowEvent we);
void windowDeiconified(WindowEvent we);
void windowActivated(WindowEvent we);
void windowDeactivated(WindowEvent we);
El uso frecuente de WindowEvent es cerrar ventanas (por defecto, los objetos de Frame slo se cierran con
Ctrl+Alt+Supr). Tambin se usa para detener threads y liberar recursos al iconizar una ventana (p. ej. con
animaciones) y comenzar de nuevo al restaurarla. WindowEvent define las constantes WINDOW_CLOSED,
WINDOW_OPENED, WINDOW_CLOSING, WINDOW_ACTIVATED, WINDOW_DEACTIVATED,
WINDOW_ICONIFIED y WINDOW_DEICONIFIED, para identificar el tipo de evento. El mtodo Window
getWindow de WindowEvent devuelve la ventana que gener el evento. Se usa en vez de getSource.
5.3.2.2. Clases InputEvent, MouseEvent y KeyEvent
La clase InputEvent engloba los eventos de ratn y teclado. Dispone mtodos para detectar botones del
ratn y teclas especiales pulsadas. Botones y teclas dan significado a las acciones del usuario. La clase
InputEvent define constantes (BUTTON1_MASK, BUTTON2_MASK, BUTTON3_MASK, SHIFT_MASK,
ALT_MASK, CTRL_MASK) para saber qu teclas o botones estaban pulsados al darse el evento.
Mtodos de InputEvent a heredar Funcin
boolean isShiftDown(), boolean Devuelven un boolean con informacin sobre si esa tecla estaba
isAltDown(), boolean isControlDown() pulsada o no
int getModifiers() Da informacin con mscara de bits de teclas y botones pulsados
long getWhen() Devuelve la hora en que se produjo el evento
Se produce un MouseEvent cuando el cursor movido por el ratn entra o sale de un componente visible en
pantalla, clicar o al pulsar o soltar un botn del ratn. Los mtodos de la interface MouseListener se
relacionan con estas acciones (mouseClicked, mouseEntered, mouseExited, mousePressed y
mouseReleased). Todos son void y reciben como argumento un objeto MouseEvent. La tabla muestra
algunos mtodos de la clase MouseEvent.

Programacin en Java 59
Mtodos heredados de la clase MouseEvent Funcin
int getClickCount() Devuelve el nmero de clicks en ese evento
Point getPoint(), int getX(), int getY() Devuelven la posicin del ratn al producirse el evento
boolean isPopupTrigger() Indica si este evento es el que dispara los mens popup
La clase MouseEvent define una serie de constantes enteras para identificar los tipos de eventos
producidos MOUSE_CLICKED, MOUSE_PRESSED, MOUSE_RELEASED, MOUSE_MOVED,
MOUSE_ENTERED, MOUSE_EXITED, MOUSE_DRAGGED.
Adems, el mtodo Component getComponent, heredado de ComponentEvent, devuelve el componente
sobre el que se ha producido el evento. Los eventos MouseEvent disponen de una segunda interface para
su gestin, MouseMotionListener, cuyos mtodos reciben como argumento un evento de MouseEvent.
stos se relacionan con el movimiento del ratn. Se llama a un mtodo de MouseMotionListener cuando el
usuario utiliza el ratn (o dispositivo similar) para mover el cursor o arrastrarlo en la pantalla. Los mtodos
de la interface MouseMotionListener son mouseMoved y mouseDragged.
Clase KeyEvent. Se produce un KeyEvent al pulsar una tecla. Como el teclado no es un componente del
AWT, es el objeto que tiene el focus en ese momento quien genera los eventos KeyEvent (el objeto que es
event source). Hay 2 tipos de KeyEvents, key-typed y key-pressed.
Key-typed, representa la introduccin de un carcter Unicode y key-pressed y key-released, representan
pulsar o soltar una tecla. Son importantes para teclas que no representan caracteres (p.ej. F1).
Para estudiar estos eventos interesan las Virtual KeyCodes (VKC), constantes que se corresponden con las
teclas fsicas del teclado, sin considerar minsculas (que no tienen VKC). Se indican con el prefijo VK_,
como VK_SHIFT o VK_A. La clase KeyEvent (del package java.awt.event) define constantes VKC para las
teclas del teclado. P.ej. escribir la letra "A" genera 5 eventos: key-pressed VK_SHIFT, key-pressed VK_A,
key-typed "A", key-released VK_A, y key-released VK_SHIFT. Las constantes de InputEvent que permiten
identificar las teclas modificadoras y botones del ratn se pueden aplicar las operaciones lgicas de bits
para detectar combinaciones de teclas o pulsaciones mltiples.
Mtodos de KeyEvent Funcin
int getKeyChar() Obtiene el carcter Unicode asociado con el evento
int getKeyCode() Obtiene el VKC de la tecla pulsada o soltada
boolean isActionKey() Indica si la tecla del evento es una ActionKey (HOME, END )
String getKeyText(int keyCode) Devuelve un String que describe el VKC, tal como "HOME", "F1" o
"A". Se definen en el fichero awt.properties
String getKeyModifiersText(int Devuelve un String que describe las teclas modificadoras, tales
modifiers) como"Shift" o "Ctrl+Shift" (fichero awt.properties)
5.4. Mens
Los Menus Java derivan de MenuComponent y presentan
comportamiento similar a los componentes, pues aceptan Events. La
figura muestra la jerarqua de clases de los Menus Java 1.1.
Para crear un Men se debe crear primero un MenuBar; despus los
Menus y los MenuItem. Los MenuItems se aaden al Menu
correspondiente; los Menus a la MenuBar y la MenuBar a un Frame.
La MenuBar se aade a un Frame con el mtodo setMenuBar, de
Frame. Tambin puede aadirse un Menu a otro para crear un
submen, razn por la que la clase Menu deriva de MenuItem.
5.4.1 Clase MenuShortcut, MenuComponent, MenuBar, MenuItem y Menu
La clase java.awt.MenuShortcut (derivada de Object) representa las teclas aceleradoras que pueden usarse
para activar mens desde teclado, sin ratn.
Mtodos de MenuShortcut Funcin
MenuShortcut(int key) Constructor
int getKey() Obtiene el cdigo virtual de la tecla utilizada como shortcut

Programacin en Java 60
Se establece un Shortcut creando un objeto de esta clase con el constructor MenuShortcut(int vk_key) y
pasndoselo al constructor adecuado de MenuItem. Los MenuShortcut de Java estn restringidos al uso la
tecla control (CTRL). Al definir el MenuShortcut no hace falta incluir dicha tecla.
Clase MenuComponent. Es la superclase derivada de Object que engloba los componentes de Mens.
Clase MenuBar. A una MenuBar slo se pueden aadir objetos Menu. La tabla muestra algunos mtodos.
Mtodos de MenuBar Funcin
MenuBar() Constructor add(Menu), int Aade un man, obtiene el nmero de mens y el men
getMenuCount(), Menu getMenu(int i) en una posicin determinada
MenuItem getShortcutMenuItem(MenuShortcut), Obtiene el objeto MenuItem relacionado con un
deleteShortcut(MenuShortcut) Shortcut y elimina el Shortcut especificado
remove(int index), remove(MenuComponent m) Elimina un objeto Menu a partir de un ndice o
referencia
Enumeration shortcuts() Obtiene un objeto Enumeration con todos los Shortcuts
Clase MenuItem. Los objetos de MenuItem representan las opciones de un men. Al seleccionar un objeto
MenuItem se generan eventos tipo ActionEvents. Se puede definir un ActionListener para cada item de un
Menu que define el mtodo actionPerformed. El mtodo getActionCommand, asociado al getSource del
evento dado no permite identificar correctamente al item cuando ste se ha activado mediante el
MenuShortcut (devuelve null).
Mtodos de MenuItem Funcin
MenuItem(String lbl), MenuItem(String, MenuShortcut) Constructores. El carcter (-) es el label de
los separators
boolean isEnabled(), setEnabled(boolean) Pregunta y determina si en item est activo
String getLabel(), setLabel(String) Obtiene y establece la etiqueta del item
MenuShortcut getShortcut(), setShortcut(MenuShortcut), Obtienen, establecen y borran
deleteShortcut(MenuShortcut) MenuShortcuts
String getActionCommand(), setActionCommand(String) Obtienen y establecen un identificador
distinto del label
Clase Menu. El objeto Menu define las opciones de un men de la barra de mens. En un Menu se pueden
introducir objetos MenuItem, otros objetos Menu (para submens), objetos CheckboxMenuItem, y
separadores. Como Menu deriva de MenuItem, add(MenuItem) permite aadir objetos Menu a otro Menu.
Mtodos de Menu Funcin
Menu(String) Constructor
int getItemCount() Obtener el nmero de items
MenuItem getItem(int) Obtener el MenuItem a partir de un ndice
add(String), add(MenuItem), addSeparator(), Aadir un MenuItem o separador
insertSeparator(int index)
remove(int index), remove(MenuComponent), Eliminar uno o todos los componentes
removeAll()
insert(String lbl, int index), insert(MenuItem Insertar items en una posicin dada
mnu, int index)
String getLabel(), setLabel(String) Obtener y establecer las etiquetas de los items
5.4.2 Clase CheckboxMenuItem y PopupMenu
Clase CheckboxMenuItem. Agrupa items de un Menu que pueden estar activados o no. Genera un
ItemEvent, de modo similar a la clase Checkbox. Esto registrar un ItemListener.
Mtodos de CheckboxMenuItem Funcin
CheckboxMenuItem(String lbl), CheckboxMenuItem(String lbl, boolean state) Constructores
boolean getState(), setState(boolean) Obtienen y ponen estado

Programacin en Java 61
Clase PopupMenu. Los mens popup son los contextuales del botn derecho del ratn (popup trigger) al
pulsar sobre un componente dado (parent Component). El men popup se muestra en unas coordenadas
relativas al parent Component, que debe estar visible. Se pueden usar los mtodos de la clase Menu, de la
que deriva. Para que aparezca el PopupMenu hay que registrar el MouseListener y definir el mtodo
mouseClicked.
Mtodos de PopupMenu Funcin
PopupMenu(), PopupMenu(String title) Constructores
show(Component origin, int x, int y) Muestra el pop-up men en la posicin indicada
5.5. Layout managers
Un Layout Manager es un objeto que controla cmo se sitan los Components (Buttons, TextAreas) en un
Container (Window, Panel) para otorgar a Java de la portabilidad necesaria entre plataformas.
El AWT define 5 Layout Managers: FlowLayout, GridLayout (sencillos), BorderLayout, CardLayout
(especializados) y GridBagLayout (genrico). El usuario pueden definir sus Layout Manager, con la interface
LayoutManager y sus 5 mtodos. Java permite posicionar los Components de modo absoluto, sin Layout
Manager, pero se pierde la portabilidad y otras caractersticas. Los Containers tienen un Layout Manager
por defecto, que se usa si no se indica otra cosa. El de Panel, por defecto, es un objeto de la clase
FlowLayout y para Window (Frame y Dialog) uno de BorderLayout. La figura muestra varios ejemplos.
En los FlowLayout los componentes
se aaden de izqda. a dcha. y de
arriba abajo. Se puede elegir
alineacin por la izquierda, centrada
o por la derecha, respecto al
container.
En la figura del BorderLayout el
container se divide en 5 zonas
(North, South, East, West y Center
que ocupa el resto de espacio).
En el ejemplo de GridLayout se usa
una matriz de celdas que se
numeran de izqda. a dcha. y de
arriba abajo.
La imagen del GridBagLayout usa tambin una matriz de celdas, permitiendo que algunos componentes
ocupen ms de una celda. Las imgenes de las CardLayout muestran cmo se permite que el mismo
espacio sea utilizado sucesivamente por contenidos diferentes. Como cada Container tiene un Layout
Manager por defecto, si se desea usarlo basta crear el Container y su constructor crea un objeto por
defecto e inicializa el Container. Para usar un Layout Manager distinto se crea un objeto de dicho Layout
Manager y se pasa al constructor del container o se le indica que lo use con el mtodo setLayout, en la
forma unContainer.setLayout(new GridLayout()). La clase Container dispone mtodos para manejar el
Layout Manager. Si se cambia de modo indirecto el tamao de un Component (p.ej. cambiando el tamao
del Font), hay que llamar al mtodo invalidate del Component y luego al mtodo validate del Container, lo
que hace que se ejecute el mtodo doLayout para reajustar el espacio disponible.
Mtodos de Container para LayoutManagers Funcin
add() Aade Components a un Container
remove() y removeAll() Permiten eliminar Components de un Container
doLayout(), validate() doLayout() se llama automticamente al redibujar el Container y
sus Components. Se llama tambin al llamar al validate
5.5.1. FlowLayout, BorderLayout y GridLayout
FlowLayout. Layout Manager por defecto para Panel. Coloca los componentes uno tras otro, en una fila, de
izqda. a dcha. y de arriba abajo. Los componentes se aaden en orden en que se ejecutan los add. Si se
cambia el tamao de la ventana se redistribuyen ocupando ms filas si es necesario. La clase tiene 3
constructores FlowLayout, FlowLayout(int alignement) y FlowLayout(int alignement, int horizontalGap, int
verticalGap). Se puede establecer la alineacin de los componentes (centrados, por defecto), con las
constantes FlowLayout.LEFT, FlowLayout.CENTER y FlowLayout.RIGHT. Es posible tambin establecer
una distancia horizontal y vertical entre componentes (gap, en pixels, 5 por defecto).

Programacin en Java 62
BorderLayout. Es el Layout Manager por defecto para Window y Frame. Define 5 reas, North, South, East,
West y Center. Si se aumenta el tamao de la ventana las zonas se mantienen en su mnimo tamao
posible excepto Center, que absorbe el crecimiento. Los componentes aadidos en cada zona tratan de
ocupar el espacio disponible. P.ej., si se aade un botn, el botn se har tan grande como la celda, lo quel
puede generar efectos raros. Para evitarlo se puede introducir en la celda un panel con FlowLayout y aadir
el botn al panel y el panel a la celda.
Los constructores de BorderLayout son BorderLayout() y BorderLayout(int horizontalGap, int verticalGap).
Por defecto no se deja espacio entre componentes. Al aadir uno a un Container con BorderLayout se debe
especificar la zona como segundo argumento (miContainer.add(new Button("Norte"), "North")).
GridLayout. Coloca los componentes en una matriz de celdas del mismo tamao. Cada componente usa
todo el espacio disponible en su celda, al igual que en BorderLayout. GridLayout tiene dos constructores
GridLayout(int nfil, int ncol) y GridLayout(int nfil, int ncol, int horizontalGap, int verticalGap). Al menos un
parmetro nfil o ncol debe ser no 0. El valor por defecto para el espacio entre filas y columnas es 0 pixels.
5.5.2. CardLayout y GridBagLayout
CardLayout. Dispone componentes (en general Panels) que comparten ventana para mostrarse
sucesivamente. Son similares a diapositivas o cartas que aparecen una tras otra. El orden se puede
establecer de la primera a la ltima, por orden de aadido al container; recorriendolas hacia delante o atrs,
de una en una; o mostrando una dada. Los constructores de esta clase son CardLayout() y CardLayout(int
horizGap, int vertGap). Para aadir componentes a un container con CardLayout se usa el mtodo
Container.add(Component comp, int index) donde index indica la posicin de la carta. Los mtodos void
first(Container cont), void last(Container cont), void previous(Container cont), void next(Container cont) y
void show(Container cont, String nameCard) permiten controlar el orden en que aparecen las diapositivas.
GridBagLayout. Es el Layout Manager ms completo y complicado. Parte de una matriz de celdas en que se
sitan los componentes. Ahora las filas pueden tener distinta altura, las columnas distinta anchura y en el
GridBagLayout un componente puede ocupar varias celdas contiguas. La posicin y tamao de cada
componente se especifican por medio de restricciones o constraints que se establecen creando un objeto de
la clase GridBagConstraints, dando valor a sus propiedades (variables miembro) y asociandolo al
componente con el mtodo setConstraints. Las variables miembro de GridBagConstraints son:
- gridx y gridy. Especifican fila y columna en que situar la esquina superior izqda. del componente
(empezando de 0). Con la constante GridBagConstraints.RELATIVE se indica que el componente
se sita relativamente al anterior componente situado (condicin por defecto).
- gridwidth y gridheight. Determinan columnas y filas que ocupar el componente. El valor por defecto
es una columna y una fila. La constante GridBagConstraints.REMAINDER indica que el componente
es el ltimo de la columna o fila. GridBagConstraints.RELATIVE indica que el componente se sita
respecto al anterior componente de la fila o columna.
- fill. En caso en que el componente sea ms pequeo que el espacio reservado, indica si debe
ocupar o no todo el espacio disponible. Los posibles valores son: GridBagConstraints.NONE (no lo
ocupa; por defecto), GridBagConstraints.HORIZONTAL (en horizontal),
GridBagConstraints.VERTICAL (en vertical) y GridBagConstraints.BOTH (en ambas direcciones).
- ipadx y ipady. Especifican el espacio a aadir en cada direccin al tamao interno del componente.
Los valores por defecto son 0. El tamao del componente ser el mnimo ms dos veces el ipadx o
el ipady.
- insets. Indica el espacio mnimo entre componente y espacio disponible. Se establece con un objeto
de la clase java.awt.Insets. Por defecto es 0.
- anchor. Se usa para determinar dnde se coloca el componente, cuando es menor que el espacio
disponible. Sus posibles valores vienen dados por las constantes de la clase GridBagConstraints:
CENTER (valor por defecto), NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST,
WEST y NORTHWEST.
- weightx y weighty. Son coeficientes entre 0.0 y 1.0 para dar ms o menos peso a filas y columnas. A
ms peso ms probabilidades de darles ms anchura o altura.
El cuadro muestra una forma tpica de crear un container con GridBagLayout y de aadir componentes:
Con las 3 primeras sentencias preparan GridBagLayout unGBL = new GridBagLayout();
para aadir los componentes. Primero se
GridBagConstraints unasConstr = new GridBagConstraints();
crea un componente unComp, se da valor
a las variables del objeto unasConstr y se unContainer.setLayout(unGBL);
asocian las restricciones al componente.
unGBL.setConstraints(unComp, unasConstr);
Por fin, la ltima sentencia aade el
componente al container. unContainer.add(unComp);

Programacin en Java 63
5.6. Grficos, texto e imgenes
La clase Component dispone los mtodos paint, repaint y update importantes en relacin a grficos. Cuando
el usuario llama al repaint de un componente, el AWT llama al mtodo update del componente, que por
defecto llama al mtodo paint.
Mtodo paint(Graphics g). Se define en la clase Component, pero no se implementa, se redefine en una
clase derivada. No hay que llamar a este mtodo porque el SO lo llama al dibujar por primera vez una
ventana y lo vuelve a llamar cada vez que toda o una parte de la ventana debe redibujarse.
Mtodo update(Graphics g). Su funcin es redibujar la ventana con el color de fondo y llamar al mtodo
paint. Update tambin es llamado por el AWT y puede ser llamado por el programador si se realiza algn
cambio en la ventana y necesita que se redibuje.
La estructura de este mtodo (comenzar con el color de fondo) hace que se produzca parpadeo (flicker) en
las animaciones. Una forma de evitarlo es redefinir el mtodo de forma diferente, cambiando de una imagen
a otra slo lo que cambia, en vez de redibujarlo todo. Este mtodo no siempre proporciona los resultados
buscados y hay que recurrrir al mtodo del doble buffer.
Mtodo repaint(). Es que se usa con ms frecuencia. Llama lo antes posible al mtodo update del
componente. Permite especificar un nmero de ms, que una vez cumplidos, se llame al update. Repaint
presenta 4 formas: repaint(), repaint(long time), repaint(int x, int y, int w, int h), repaint(long time, int x, int y,
int w, int h). La tercera y cuarta forma permiten definir una zona de la ventana a la que aplicar el mtodo.
Java dispone los mtodos (o primitivas grficas) de la tabla para realizar dibujos sencillos. Las coordenadas
se miden en pixels, empezando de 0. Excepto los polgonos y lneas, las formas geomtricas se determinan
por el rectngulo que las comprende, de dimensiones w y h. Los polgonos admiten un argumento de la
clase java.awt.Polygon. Los mtodos draw3DRect, fill3DRect, drawOval, fillOval, drawArc y fillArc dibujan
objetos de tamao total (w+1, h+1) pixels.
Mtodo grfico Funcin
drawLine(int x1, int y1, int x2, int y2) Dibuja una lnea entre dos puntos
drawRect(int x1, int y1, int w, int h) Dibuja un rectngulo (w-1, h-1)
fillRect(int x1, int y1, int w, int h) Dibuja un rectngulo y rellena con color actual
clearRect(int x1, int y1, int w, int h) Borra dibujando con el background color
draw3DRect(int x1, int y1, int w, int h, boolean raised) Dibuja un rectngulo resaltado (w+1, h+1)
fill3DRect(int x1, int y1, int w, int h, boolean raised) Rellena un rectngulo resaltado (w+1, h+1)
drawRoundRect(int x1, int y1, int w, int h, int arcw, int arch), Dibuja y rellena un rectngulo redondeado,
fillRoundRect(int x1, int y1, int w, int h, int arcw, int arch) respectivamente
drawOval(int x1, int y1, int w, int h), fillOval(int x1, int y1, int Dibuja y rellena de un color una elipse,
w, int h) respectivamente
drawArc(int x1, int y1, int w, int h, int startAngle, int Dibuja y rellena un arco de elipse (ngulos en
arcAngle), fillArc(int x1, int y1, int w, int h, int startAngle, int grados) respectivamente
arcAngle)
drawPolygon(int x[], int y[], int nPoints) Dibuja y cierra el polgono de modo
automtico
drawPolyline(int x[], int y[], int nPoints) Dibuja un polgono pero no lo cierra
fillPolygon(int x[], int y[], int nPoints) Rellena un polgono
5.6.1. Clase Graphics y Font
El nico argumento de los mtodos update y paint es un objeto de clase
Graphics, que dispone mtodos para soportar 2 tipos de grficos el
dibujo de primitivas grficas (texto, lneas, crculos) y la presentacin
de imgenes en formatos *.gif y *.jpeg. La clase Graphics mantiene un
contexto grfico: un rea de dibujo actual, color de dibujo del
background y foreground, un font con sus propiedades, etc. La figura
muestra el sistema de coordenadas usado en Java. Como es habitual
en Informtica, los ejes se sitan en la esquina superior izqda. y las
coordenadas se miden en pixels.

Programacin en Java 64
La clase Graphics permite dibujar texto alternativo al texto de los componentes Label, TextField y TextArea.
Los mtodos son drawBytes(byte data[], int offset, int length, int x, int y), drawChars(char data[], int offset, int
length, int x, int y) y drawString(String str, int x, int y). Los argumentos x e y representan las coordenadas de
la lnea base. Offset indica el elemento que se empieza a imprimir. Cada tipo de letra se representa con un
objeto Font. Las clases Component y Graphics disponen los mtodos setFont y getFont. El constructor de
Font es de la forma Font(String name, int style, int size), donde style se indica con las constantes
Font.PLAIN, Font.BOLD y Font.ITALIC, que se pueden combinar en la forma: Font.BOLD | Font.ITALIC.
La clase Font tiene 3 variables protected, name, style y size y 3 constantes enteras, PLAIN, BOLD e ITALIC.
Dispone los mtodos String getName, int getStyle, int getSize, boolean isPlain, Boolean isBold y boolean
isItalic. Para mejorar la portabilidad se recomienda usar nombres lgicos de fonts.
5.6.2. Clase FontMetrics y Color
La clase FontMetrics es una clase abstract que permite
obtener informacin sobre una fuente y el espacio que
ocupa un char o String usando esa font. Es til si se
pretende rotular algo de modo centrado y bien
dimensionado. La forma de trabajo es por tanto, crear
subclases. Java resuelve esta dificultad al proveer
como variable miembro un objeto de clase Font. As, un
objeto de FontMetrics contiene informacin sobre la
fuente que se pasa como argumento al constructor.
La forma general para obtener esa informacin es a partir de un objeto Graphics que tenga un Font definido.
Esto permite obtener una referencia FontMetrics en la forma FontMetrics miFontMet = g.getFontMetrics().
Queda claro que se usa una referencia de FontMetrics para refererirse a un objeto de una clase derivada en
el API de Java. Con una referencia de tipo FontMetrics se pueden usar los mtodos propios de la clase. La
tabla muestra algunos mtodos FontMetrics, para los que tener en cuenta la figura anterior.
Mtodo grfico Funcin
FontMetrics(Font font) Constructor
int getAscent(), int getMaxAscent() Permiten obtener el Ascent actual y mximo para esa font
int getDescent(), int getMaxDescent() Permiten obtener el Descent actual y mximo para esa font
int getHeight(), int getLeading() Obtienen la distancia entre lneas y entre descender y
ascender entre lneas
int getMaxAdvance() Da la mxima anchura de un carcter de esa font, incluyendo
el espacio hasta el siguiente carcter
int charWidth(int ch), int charWidth(char Dan la anchura de un carcter (incluyendo el espacio hasta el
ch), int stringWidth(String str) siguiente carcter) o de toda una cadena de caracteres
int charsWidth(char data[], int start, int len), Anchura de un array de caracteres o bytes. Permiten definir la
int bytesWidth(byte data[], int start, int len) posicin del comienzo y el nmero de caracteres
Clase java.awt.Color. Encapsula colores en formato RGB (Red, Green, Blue). Los componentes de cada
color primario en el color resultante se expresan con enteros entre 0 y 255, siendo 0 la intensidad mnima.
Mtodos de Color Funcin
Color(int), Color(int,int,int), Constructores. 3 B en un int (del bit 0 al 23), con enteros entre 0
Color(float,float,float) y 255 y float entre 0.0 y 1.0
Color brighter(), Color darker() Obtienen una versin ms o menos brillante de un color
Color getColor(), int getRGB() Obtiene un color en los tres primeros bytes de un int
int getGreen(), int getRed(), int getBlue() Componentes de un color
Color getHSBColor() Color a partir de los valores de hue, saturation y brightness
(entre 0.0 y 1.0)
float[] RGBtoHSB(int,int,int,float[]), int Mtodos static para convertir colores entre sistemas
HSBtoRGB(float,float,float)
En la clase Color existen constantes para colores predeterminados de uso frecuente: black, white, green,
blue, red, yellow, magenta, cyan, orange, pink, gray, darkGray, lightGray.

Programacin en Java 65
5.6.3. Imgenes
Java permite incorporar imgenes de tipo gif y jpeg definidas en ficheros con la clase java.awt.Image. Para
cargar una imagen hay que indicar la localizacin del fichero (URL) y cargarlo con los mtodos Image
getImage(String) o Image getImage(URL, String) de las clases awt.Toolkit y Applet. El argumento de tipo
String representa una variable con el nombre del fichero.
Cuando las imgenes se cargan en applets, para obtener el URL pueden ser tiles getDocumentBase y
getCodeBase, que devuelven el URL del fichero HTML que llama al applet y el directorio que contiene el
applet (en un String). Para cargar una imagen hay que crear un objeto Image y llamar al mtodo getImage,
pasndole como argumento el URL (p.ej. Image miImagen = getImage(getCodeBase(), "imagen.gif")).
Cargada la imagen, hay que representarla, con el mtodo paint para llamar al mtodo drawImage de
Graphics. ste mtodo admite varias formas, aunque casi siempre hay que incluir el nombre del objeto
imagen creado, dimensiones de imagen y un objeto ImageObserver.
ImageObserver es un interface que declara mtodos para observar el estado de la carga y visualizacin. Si
se programa un applet, basta con poner como ImageObserver la referencia this, ya que en la mayora de
casos, la implementacin del interface en la clase Applet proporciona el comportamiento deseado. La clase
Image define constantes para controlar los algoritmos de cambio de escala: SCALE_DEFAULT,
SCALE_FAST, SCALE_SMOOTH, SCALE_REPLICATE, SCALE_AVERAGE.
Mtodos de Image Funcin
Image() Constructor
int getWidth(ImageObserver), Determinan la anchura y la altura de la imagen. Si no se conocen,
int getHeight(ImageObserver) devuelve -1 y el ImageObserver especificado ser notificado ms tarde
Graphics getGraphics() Crea contexto grfico para dibujar en una imagen no visible en pantalla.
Este mtodo slo se puede llamar para objetos no visibles en pantalla
Object getProperty(String, Obtiene una propiedad de una imagen a partir del nombre de la
ImageObserver) propiedad
Image getScaledInstance(int w, Crea una versin de la imagen a otra escala. Si w o h son negativas se
int h, int hints) usa la otra dimensin manteniendo la proporcin. El ltimo argumento es
informacin para el algoritmo de cambio de escala
5.7. Animaciones
Se pueden hacer animaciones de forma sencilla definiendo el mtodo paint de forma que cada vez dibuje
algo diferente. Como una pelcula. En general se llamar a repaint en un bucle que incluya una llamada a
sleep, que espere unos ms entre frames. Repaint llama a update; update borra redibuja con el color de
fondo y llama a paint. Es una forma vlida con animaciones sencillas, pero produce parpadeo (flicker) con
grficos complejos. La razn es el refresco de pantalla y la pesadez del proceso.
Para eliminar el flicker se puede redefinir update. Una posibilidad es no redibujar todo con el color de fondo,
no llamar a paint e introducir en update el cdigo que dibuja, slo los cambios. As, es necesario redefinir
paint pues es al que se llama automticamente cuando la ventana de Java es tapada con otra que se retira.
Una posible solucin es hacer que paint llame a update, terminando por establecer un orden de llamadas
opuesto al de defecto. Al no borrar todo lo pintando con el color de fondo, hay que borrar de forma selectiva
entre frame y frame lo que sea. Los mtodos setClip y clipRect de Graphics permiten hacer que las
operaciones grficas no surtan efecto fuera de un rea rectangular previamente dada. Al ser dependiente
del tipo de grficos concretos de que se trate, el mtodo no siempre es adecuado.
La tcnica del doble buffer supone otra solucin, aunque de ms programacin. La Image imgInv;
idea es realizar los dibujos en una imagen invisible, distinta a la mostrada y
Graphics graphInv;
mostrarla al terminarla para que aparezca rpido. El segundo buffer o imagen
invisible obliga a crear un objeto Image del mismo tamao que la imagen mostrada Dimension dimInv;
y un contexto grfico u objeto Graphics para dibujar sobre la imagen invisible. Esto
Dimension d = size();
se hace con las sentencias del cuadro en la clase que controle el dibujo.
En el update se modificar el cdigo de forma quee primero se dibuje en la imagen invisible y luego se haga
visible. En el cuadro se muestra un cdigo tipo.
public void update (Graphics.g) {
// se comprueba si existe el objeto invisible y si sus dimensiones son correctas

Programacin en Java 66
if ((graphInv==null) || (d.width!=dimInv.width) || (d.height!=dimInv.height)) {
dimInv = d;
imgInv = createImage(d.width, d.height); // se llama al mtodo createImage de Component
graphInv = imgInv.getGraphics(); // se llama al mtodo getGraphics de la clase Image
}
graphInv.setColor(getBackground()); // propiedades del contexto invisible y se dibuja sobre l
...
g.drawImage(imgInv, 0, 0, this); // se hace visible la imagen invisible a partir de (0, 0)
} // fin de update

Programacin en Java 67
6. THREADS
La multitarea es la realizacin aparentemente simultnea de 2 o ms actividades. Los SO ejecutan varios
programas a la vez aunque slo dispongan una CPU: reparten el tiempo entre las actividades, o usan los
tiempos de espera para adelantar otras tareas. En equipos con dos o ms procesadores la multitarea es
real, ya que cada procesador ejecuta un hilo o thread distinto.
Un proceso es un programa ejecutndose de forma independiente con espacio propio de memoria. Un
thread o hilo es un flujo secuencial simple en un proceso. Un nico proceso puede tener varios hilos
ejecutndose. Por ejemplo un navegador sera un proceso y cada ventana abierta estara formada por al
menos un hilo.
Los threads o hilos de ejecucin permiten organizar los recursos del ordenador entre varios programas en
paralelo. Un hilo puede realizar cualquier tarea de un programa normal. Basta con indicarlo en el mtodo
run, el que define la actividad principal de los hilos. Los threads pueden ser daemon o no.
Son daemon los hilos que realizan en background (segundo plano) servicios generales; tareas que no
forman parte del ncleo del programa y se ejecutan mientras no finalice la aplicacin. Por ejemplo el control
de la pulsacin de un botn. Un programa Java finaliza cuando slo quedan threads de tipo daemon.
En Java hay 2 formas de crear threads: crear una nueva clase que herede de java.lang.Thread y
sobrecargar el mtodo run de dicha clase o declarar una clase que implemente la interface
java.lang.Runnable, que declare el mtodo run. As, se crear un objeto Thread pasndole como argumento
al constructor el objeto creado. Tanto la clase Thread como la interface Runnable pertenecen al package
java.lang, por lo que no es necesario importarlas.
A la derecha se muestra un ejemplo de creacin de threads derivando de la clase Thread. Se crea la clase
SimpleThread donde su constructor usa un string (opcional) para nombrar el thread creado y con super
invocar el constructor de Thread. Tambin redefine el mtodo run, para que escriba 10 veces el nombre del
thread creado.
public class SimpleThread extends Thread { public class SimpleRunnable implements Runnable {
public SimpleThread (String str) { // constructor String nameThread; // se crea un nombre
super(str); public SimpleRunnable (String str) { // constructor
} nameThread = str;
public void run() { // redefinicin del mtodo run() }
for(int i=0;i<10;i++) public void run() { // definicin del mtodo run()
System.out.println("Nombre Thread: " + getName()); for(int i=0;i<10;i++)
} System.out.println("Nombre Thread: " +
nameThread);
}
}}
Para iniciar el nuevo thread se ha de crear un objeto de la clase SimpleThread y llamar al start heredado de
Thread (que llama a run). Por ejemplo:
SimpleThread miThread = new SimpleThread(Hilo de prueba);
miThread.start();
A la izquierda se muestra un ejemplo de creacin de threads implementando la interface Runnable.
Tambin requiere que se defina el mtodo run y es necesario crear un objeto de la clase Thread para lanzar
la ejecucin del nuevo hilo. Al constructor de la clase Thread hay que pasarle una referencia del objeto de la
clase que implementa la interface Runnable. Posteriormente, cuando se ejecute el start del thread, ste
llamar al run de la nueva clase.
El siguiente cdigo de la derecha crea un nuevo thread y lo ejecuta con este procedimiento. Este mtodo es
interesante con applets, que heredan de java.applet.Applet y por tanto no de Thread. En el cdigo de la
izquierda, el argumento this del constructor de Thread hace referencia al objeto Runnable cuyo run debera
llamarse cuando el hilo ejecutado es un objeto ThreadRunnable.
La eleccin de una u otra forma (derivar de Thread o implementar Runnable) depende del tipo de clase a
crear. Si la clase hereda de otra (por ejemplo un applet) no hay ms que implementar Runnable, aunque
suele ser ms sencillo heredar de Thread.

Programacin en Java 68
SimpleRunnable p = new SimpleRunnable("Hilo de class ThreadRunnable extends Applet implements
prueba"); Runnable {
// se crea un objeto Thread pasando el objeto private Thread runner=null;
Runnable como argumento
public void start() { // redefine el start de Applet
Thread miThread = new Thread(p);
if (runner == null) {
// se arranca el objeto de la clase Thread
runner = new Thread(this);
miThread.start();
runner.start(); // se llama al start de Thread
}}
public void stop(){ // redefine el stop de Applet
runner = null; // se libera el objeto runner
}}
6.1. Ciclo de vida de un thread
En la figura se muestran los estados por los que
puede pasar un thread en su vida. Son 4:
Nuevo (New). El thread se crea pero no se inicializa;
no se ha ejecutado el mtodo start. Se producir un
mensaje de error (IllegalThreadStateException) si se
intenta ejecutar cualquier mtodo de la clase Thread
distinto de start.
Ejecutable (Runnable). El thread puede estar ejecutndose, siempre y cuando se le haya asignado tiempo
de CPU. En la prctica puede no estar siendo ejecutado en un instante dado en beneficio de otro thread.
Bloqueado (Blocked o Not Runnable). Podra estar ejecutndose, pero hay alguna actividad propia interna
que lo impide, como por ejemplo una espera producida una operacin E/S de datos por teclado. A un thread
bloqueado no se le asigna tiempo de CPU.
Muerto (Dead). La forma habitual de que un thread muera es finalizando el mtodo run. Tambin puede
llamarse al mtodo stop de Thread, aunque es considerado peligroso.
Estos estados dan lugar a 4 operaciones sobre threads: ejecucin, detencin y finalizacin.
La creacin de un nuevo thread no implica que se empiece a ejecutar algo. Hace falta iniciarlo con el
mtodo start, que se encarga de llamar al mtodo run de Thread. Si el nuevo thread se ha creado
heredando de Thread la nueva clase deber redefinirirlo. En caso de implementar la interface Runnable, el
mtodo run de Thread llamar al de la nueva clase. Una vez que el mtodo start se llama, el thread est
corriendo (running), que no es que se est ejecutando en todo momento, pues el tiempo de CPU se divide
entre todos. Por eso se dice que el thread es runnable.
La detencin de un thread temporalmente depende del SO. El tiempo de CPU asignado a cada thread en
estado runnable lo emplean en ejecutar su mtodo run. Un thread puede renunciar a su tiempo de CPU
para que se asigne a otro. Esa renuncia se realiza con el mtodo yield, importante para actividades que
tienden a monopolizar la CPU. Yield viene a indicar que en ese momento el thread puede liberar tiempo de
CPU. En caso que sobre tiempo se vuelve a asignar al thread generoso que us yield: ser generoso no es
contraproducente. Parar o bloquear temporalmente un thread (estado Not Runnable), se puede hacer:
1. Ejecutando el mtodo sleep de Thread. Esto detiene el thread un tiempo dado. En general sleep se llama
desde el run.
2. Ejecutando el mtodo wait heredado de Object. Queda a la espera que suceda algo necesario para
continuar. El thread volver a runnable con los mtodos notify o notifyAll, que se ejecutarn al cesar la
condicin que detiene el thread.
3. Cuando el thread est esperando a realizar operaciones de E/S.
4. Cuando el thread llama a un mtodo synchronized de un objeto que est bloqueado por otro thread.
Un thread pasa automticamente de estado Not Runnable a Runnable cuando cesa alguna condicin
anterior o cuando se llama a notify o notifyAll. La clase Thread dispone tambin del mtodo stop, pero no es
aconsejable, ya que puede provocar bloqueos del programa (deadlock). Otra posibilidad para detener un
thread, es ejecutar el mtodo suspend. El thread volver a ser ejecutable ejecutando el mtodo resume.

Programacin en Java 69
Esta ltima forma tambin se desaconseja, por razones similares a las de stop. El mtodo sleep de Thread
recibe como argumento el tiempo en ms que ha de detenerse. Adicionalmente, se puede incluir un nmero
entero con un tiempo adicional en ns. Los prototipos de estos mtodos son:
public static void sleep(long millis) throws InterruptedException
public static void sleep(long millis, int nanosecons) throws InterruptedException
Sea el ejemplo del cuadro. El mtodo sleep lanza una System.out.println ("CuentaSegundos");
InterruptedException que se captura, aunque no se gestiona.
int count=0;
Para detener temporalmente un thread es preferible usar
conjuntamente wait y notifyAll. La ventaja del wait es que libera public void run () {
el bloqueo del objeto por lo que el resto de threads en espera
try {
para actuar sobre l pueden llamar a sus mtodos. Hay 2
formas de llamar a wait: sleep(1000);
1. Indicando el tiempo mximo a parar. En ms y con la opcin System.out.println(count++);
de indicarlo en ns, de forma anloga a sleep. A diferencia del
mtodo sleep, que slo detiene el thread el tiempo indicado, el } catch (InterruptedException e){}
wait establece el tiempo mximo que debe estar parado. }
Si en ese plazo se ejecutan notify o notifyAll que indican la liberacin de los objetos bloqueados, el thread
continuar sin esperar a concluir el tiempo. Los 2 prototipos de wait son:
public final void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
2. Sin argumentos. En cuyo caso el thread permanece parado hasta que sea reinicializado explcitamente
con mtodos notify o notifyAll: public final void wait() throws InterruptedException.
Los mtodos wait y notify han de estar public class MyApplet extends Applet implements Runnable {
incluidos en un mtodo synchronized, ya
private Thread AppletThread; // Se crea referencia Thread
que de otra forma se obtendr una
excepcin del tipo ...
IllegalMonitorStateException en tiempo de
public void start() { // mtodo start() del Applet
ejecucin. El uso tpico de wait es esperar
a que se cumpla alguna condicin, ajena al if(AppletThread == null){ // sin objeto Thread asociado
thread. Cuando sta se cumple, se usar
el mtodo notifyAll para avisar a los AppletThread = new Thread(this, "El propio Applet");
threads que pueden usar el objeto. AppletThread.start(); // arranca el thread y run
Un thread finaliza cuando el mtodo run }
devuelve el control, por haber terminado o
dejar de cumplirse una condicin (p. ej. un }
bucle while en el mtodo run). Es habitual public void stop() { // mtodo stop() del Applet
poner las sentencias del ejemplo de la
derecha en Applets Runnables. AppletThread = null; // iguala la referencia null

Se aprecia que AppletThread es el thread }


que ejecuta el mtodo run MyApplet. Para // mtodo run (implementa Runnable)
finalizar el thread basta poner la referencia
AppletThread a null. Esto se consigue en el public void run() {
ejemplo con el mtodo stop del applet Thread myThread = Thread.currentThread();
(distinto al de la clase Thread, que no
conviene usar). while (myThread == AppletThread) { // hasta el stop de
Thread
Para saber si un thread est vivo o no, es
til el mtodo isAlive de Thread, que ... // cdigo a ejecutar
devuelve true si el thread ha sido }
inicializado y no parado, y false si es
todava nuevo (no ha sido inicializado) o ha }
finalizado. } // fin de la clase MyApplet
6.2. Sincronizacin y prioridad
La sincronizacin nace de la necesidad de evitar que 2 o ms threads traten de acceder al mismo recurso
simultneamente, como por ejemplo en una escritura de un fichero o datos que ofrece otro thread. El cdigo
de un programa que accede a un recurso desde 2 threads distintos es una seccin crtica (critical sections).

Programacin en Java 70
Para sincronizar threads se usa synchronized en los public synchronized void metodoSincronizado() {
mtodos del objeto recurso que puedan generar
... // accediendo p. ej. a variables de un objeto
situaciones conflictivas. As, Java bloquea (asocia
un bloqueo o lock) con el recurso sincronizado. }
El cuadro derecho muestra un ejemplo de sintaxis. La sincronizacin previene interferencias slo sobre un
tipo de recurso: la memoria. Cuando se prev que variables de una clase den problemas de sincronizacin,
se deben declarar private (o protected). As, slo sern accesibles con mtodos de la clase, que deben
sincronizarse. Si se sincronizan mtodos de un objeto y otros no, el programa puede dar problemas al poder
acceder los mtodos no sincronizados a las variables miembro, ignorando el bloqueo.
Slo los mtodos sincronizados comprueban si un objeto est bloqueado. Los mtodos que accedan a un
recurso compartido deben declararse synchronized. Cuando un mtodo accede a un recurso, Java lo
bloquea; el resto de threads no pueden acceder al mismo hasta que el primero en acceder termine su tarea.
Existen 2 niveles de bloqueo: a nivel de objeto y de clase. El primero se consigue declarando todos los
mtodos de una clase synchronized. Cuando se ejecuta un mtodo synchronized sobre un objeto el sistema
lo bloquea, de forma que si otro thread intenta ejecutar algn mtodo de ese objeto, tendr que esperar. Si
existen varios objetos de una clase, como el bloqueo es a nivel de objeto, es posible tener distintos threads
ejecutando mtodos sobre diversos objetos de una misma clase.
El bloqueo a nivel de clase es el de los mtodos de clase o static, y por tanto con variables de clase o static.
Si se desea que un mtodo bloquee una clase entera hay que declararlo synchronized static. As, ningn
mtodo sincronizado acceder a ningn objeto de la clase. La sincronizacin puede ser problemtica. Un
thread podra bloquear un recurso indefinidamente.
Si en un mtodo sincronizado se usa el sleep de public synchronized int get() {
Thread, el objeto bloqueado permanecer en ese
while (available == false) {
estado el tiempo indicado.
try {
Para evitarlo conviene sustituir sleep por el wait de
Object. Al llamar a wait (siempre desde un mtodo o wait(); // Espera que put genere el dato
bloque synchronized) se libera el bloqueo del objeto
y puede continuar usndose con mtodos } catch (InterruptedException e) { }
sincronizados. Wait detiene el thread hasta que se }
llame a notify, notifyAll o finalice el tiempo indicado.
El mtodo unObjeto.notify lanza una seal indicando available = false;
al sistema que puede activar un thread bloqueado notifyAll(); // notifica que ha ledo
esperando acceso al objeto.
return contents; // devuelve el valor
NotifyAll lanza una seal a todos los threads en
espera de la liberacin del objeto. Los mtodos }
notify y notifyAll deben llamarse desde el thread que public synchronized void put(int value) {
bloquea el objeto para activar el resto de threads
que estn esperando. Un thread se convierte en while (available == true) {
propietario del bloqueo ejecutando un mtodo try { // Espera que get lea el valor
sincronizado del objeto.
wait();
Los bloqueos de tipo clase, se consiguen ejecutando
un mtodo sincronizado de clase (synchronized } catch (InterruptedException e) { }
static). El cuadro presenta 2 funciones, put que }
genera un dato y get que lo recoge. El bucle while
del get se ejecuta (avalaible==false) hasta que el put contents = value; // ofrece otro valor
suministre un nuevo valor y lo indique con avalaible available = true; // declara disponible
(= true). En cada iteracin del while el wait hace que
el hilo que ejecuta el get se detenga hasta que se notifyAll(); // lo notifica
produzca un mensaje de cambio (en este caso con }
el notifAll del put). Put funciona de forma homloga.
Existe la posibilidad de sincronizar una parte de un mtodo sin bloquear el objeto desde el comienzo hasta
el fin del mtodo, con syncronized y entre parntesis el objeto a sincronizar. El siguiente cdigo de la
derecha, muestra un ejemplo para sincronizar el propio thread en una parte del mtodo run.
public void run() { public class VolverAAdquirir {
while(true) { public synchronized void a() {
... b();

Programacin en Java 71
syncronized(this) { // El objeto a sincronizar es el thread System.out.println("En a()");
... // Cdigo sincronizado }
} public synchronized void b() {
try { // Se detiene el thread 0.5 s pero el objeto es System.out.println("En b()");
sleep(500); // accesible a otros threads al no estar sincronizado }
} catch(InterruptedException e) {} }
}}
Un thread puede llamar a un mtodo sincronizado de un objeto para el que ya posee el bloqueo, volviendo a
adquirirlo. Es lo que muestra el cdigo de la derecha, que obtendra como resultado En b(), En a(). Se ha
podido acceder al objeto con el mtodo b() al ser el thread que ejecuta el mtodo a() propietario anterior del
bloqueo del objeto. La sincronizacin lleva bastante tiempo a la CPU, luego se debe intentar minimizar.
La prioridad intenta conseguir un reparto eficiente de recursos en la ejecucin de los threads. As, si en un
momento interesa que un proceso acabe lo antes posible, se le otorgarn ms recursos (tiempo de CPU).
Cuando se crea un thread, ste hereda la prioridad del thread que lo inicializa. Las prioridades se marcan
con variables enteras miembro de la clase Thread. En general, la mxima prioridad es 10 (MAX_PRIORITY)
y la mnima 1 (MIN_PRIORITY). Por defecto se asigna 5 (NORM_PRIORITY). Para modificarla se usa el
mtodo setPriority. El valor lo da getPriority. El algoritmo de distribucin de recursos en Java suele escoger
el thread de prioridad mayor, aunque no siempre, para evitar que los procesos se duerman.
Entre 2 o ms threads de la misma prioridad (y adems la mayor), el sistema no establece prioridades; los
ejecuta alternativamente dependiendo del SO, que si soporta time-slicing (troceo temporal), los threads se
ejecutan alternativamente. Con yield, un thread renuncia a su tiempo de CPU en favor de otro de la misma o
mayor prioridad, nunca otro de menor prioridad.
6.3. Grupos de Threads
Todo hilo Java forma parte de un grupo de hilos (ThreadGroup).
Puede pertenecer al grupo por defecto o a uno creado por el
usuario. Los grupos de threads suponen una forma sencilla de
manejar mltiples threads como un solo objeto.
Por ejemplo es posible parar varios threads con una sola llamada.
Una vez un thread ha sido asociado a un threadgroup, no puede
cambiar. Cuando se arranca un programa, el sistema crea un
ThreadGroup llamado main.
Si en la creacin de un nuevo thread no se especifica su grupo, automticamente pertenece al threadgroup
del thread que lo crea (current thread group y current thread, respectivamente). Si en dicho programa no se
crea ningn ThreadGroup adicional, sus threads pertenecern al grupo main (donde se encuentra el mtodo
main). La figura presenta una posible distribucin de threads en grupos.
Para conseguir que un thread public Thread (ThreadGroup grupo, Runnable destino)
pertenezca a un grupo dado, hay
public Thread (ThreadGroup grupo, String nombre)
que indicarlo al crear el nuevo
thread, con uno de los public Thread (ThreadGroup grupo, Runnable destino, String nombre)
constructores del cuadro.
A su vez, un ThreadGroup debe pertenecer a otro ThreadGroup. Como ocurra en el caso anterior, si no se
especifica ninguno, el nuevo grupo pertenecer al ThreadGroup desde el que se crea (por defecto al grupo
main). La clase ThreadGroup los 2 posibles constructores del siguiente cuadro.
El segundo toma como parent el threadgroup al cual ThreadGroup(ThreadGroup parent, String nombre);
pertenezca el thread desde el que se crea,
ThreadGroup(String name);
Thread.currentThread().
En la prctica los ThreadGroups no se suelen usar demasiado. Su uso prctico se limita a efectuar algunas
operaciones de forma ms simple que de forma individual. En el siguiente cdigo se crea un grupo de
threads (miThreadGroup) y un thread que pertenece a dicho grupo (miThread).
ThreadGroup miThreadGroup = new ThreadGroup("Mi Grupo de Threads");
Thread miThread = new Thread(miThreadGroup, un thread para mi grupo");

Programacin en Java 72
7. APPLETS
Un applet es un programa pequeo que se aloja en cdigo de otro lenguaje (tpicamente HTML; etiqueta
<APPLET>) y se ejecuta en el contexto de una aplicacin anfitriona (tpicamente un navegador).
Los ficheros Java compilados (.class) se descargan desde un servidor web o HTTP al navegador en cuya
JVM se ejecutan. Pueden incluir ficheros de imgenes y sonido. Los applets no tienen ventana propia. Se
ejecutan en la ventana del navegador (en un panel).
Por la naturaleza de Internet, tienen implicaciones de seguridad: slo pueden leer y escribir ficheros en el
servidor del que se descargan; acceder slo a informacin limitada del equipo en que se ejecutan, etc. Las
applets de confianza (trusted applets) pueden superar estas restricciones, con condiciones.
Aunque el entorno de ejecucin es un navegador, pueden probarse sin necesidad del mismo, con la
aplicacin appletviewer del JDK de Sun.
Las applets no tienen mtodo main. Su ejecucin la asumen otros mtodos. Todas
derivan de la clase java.applet.Applet. La figura su jerarqua de clases. Las applets
deben redefinir mtodos heredados de Applet como init, start, stop o destroy.
Otros mtodos heredados son relativos a la GUI (AWT). Los mtodos grficos se
heredan de Component y la capacidad de aadir elementos de GUI de Container y
Panel. Las applets suelen redefinir ciertos mtodos grficos. Los ms importantes
paint, update (de Component y Container) y repaint (de Component).
Las applets disponen de mtodos relacionados con la obtencin de informacin,
como getAppletInfo, getAppletContext, getParameterInfo, getParameter,
getCodeBase, getDocumentBase e isActive.
El mtodo showStatus se usa para mostrar informacin en la barra de estado del navegador. Otros mtodos
relacionados con imgenes y sonido son getImage, getAudioClip, play, etc.
Los mtodos que controlan la ejecucin de las applets suelen redefinirse, pero no se llaman, lo hace el
navegador. Los mtodos que suelen redefinirse son cuatro.
Mtodo init. Se llama automticamente cuando el navegador carga el applet. Gestiona de las tareas de
inicializacin, realizando las funciones del constructor (al que el navegador no llama).
Mtodo start. Se llama automticamente en cuanto el applet se hace visible, tras inicializarse. Tambin cada
vez que el applet se hace de nuevo visible despus de estar oculta (por dejar de estar activa la pgina del
navegador, cambiar su tamao). Es habitual crear threads en este mtodo para las tareas que, por el
tiempo requerido, dejaran sin recursos al applet o al navegador (animaciones).
Mtodo stop. Se llama automticamente al ocultar el applet. Para no consumir recursos se suelen parar los
threads en ejecucin en el applet.
Mtodo destroy. Se llama a este mtodo para liberar los recursos reservados del applet (excepto la
memoria) cuando va a descargarse. No suele ser necesario redefinirlo, pues el que se hereda es completo.
7.1. Inclusin de un applet en una pgina html y paso de parmetros
Los applets son aplicaciones grficas que aparecen en una zona de la ventana del navegador, lo que obliga
a redefinir los mtodos grficos paint y update. Paint se declara como public void paint(Graphics g).
El objeto grfico g pertenece a java.awt.Graphics, que debe importar el applet. Define un contexto grfico
para dibujar (mtodos grficos, colores, fonts) y es creado por el navegador. Las tareas del applet (dibujo
de lneas, texto, etc.) se incluye en el mtodo paint, porque es llamado cuando el applet se dibuja por
primera vez y de forma automtica cada vez que el applet se debe redibujar.
En general se crea el mtodo paint pero no se llama. Para solicitar al sistema que vuelva a dibujar el applet
(por algn cambio, p.ej.) se usa el mtodo repaint, ms fcil de usar, al no requerir argumentos. Repaint
llama a paint a travs de update, que borra todo y pinta de nuevo con el color de fondo y luego llama a
paint. A veces produce parpadeo de pantalla (flickering).
Para evitarlo se puede redefinir update de forma que no borre toda la ventana, slo lo necesario o se puede
redefinir paint y update para usar doble buffer.
Para incluir un applet en una pgina HTML se usa la etiqueta <APPLET>, de sintaxis la del cuadro. NAME
permite dar un nombre opcional al applet para comunicarse con otras applets o elementos que se ejecuten
en la misma pgina. Si las clases se comprimen en ficheros jar o zip, se pueden especificar entre comas
con otro indicador opcional, ARCHIVE. Los modificadores ALIGN, VSPACE y HSPACE tienen el mismo
significado que en el tag IMG de HTML.

Programacin en Java 73
Las etiquetas PARAM <APPLET CODE="Applet.class" [CODEBASE="URL"] [NAME="Name"]
permiten pasar
WIDTH="wpixels" HEIGHT="hpixels"
parmetros del fichero
HTML al applet, de forma [ALT="TextoAlternativo para navegadores que no pueden ejecutar el applet"]>
anloga al paso de
[<PARAM NAME="Name1" VALUE="valueOfName1">]
argumentos a main. Cada
parmetro tiene un [<PARAM NAME="Name2" VALUE="valueOfName2">]
nombre y valor dados en
forma de String, aunque [texto alternativo para navegadores que no reconocen el tag <applet>]
el valor sea numrico. </APPLET>
El applet recupera los parmetros y si es necesario, convierte los strings a valor numrico. El valor de los
parmetros se obtienen con el mtodo de Applet String getParameter(String name). La conversin de
strings a tipos primitivos se puede hacer con los mtodos asociados a los wrappers que Java ofrece para
tipos fundamentales (Integer.parseInt(String), Double.valueOf(String)).
En los nombres de los parmetros no se distingue entre maysculas y minsculas, pero s en los valores, ya
que sern interpretados por un programa Java. Es bueno prever valores por defecto para los parmetros del
applet, para el caso en que la pgina HTML que llama al applet no los defina. El mtodo getParameterInfo
devuelve una matriz de Strings con informacin sobre cada parmetro soportado por el applet: nombre, tipo
y descripcin, cada uno de ellos en un String. Este mtodo debe ser redefinido y al confeccionar la pgina
que llama al applet. Supone una forma de que el programador del applet pase informacin al usuario.
7.2. Carga de applets
Para localizar los ficheros .class que contienen el applet se supone que residen en el mismo directorio que
el fichero HTML. Si el applet es de un package, el navegador usa su nombre para construir un path relativo
al directorio del fichero HTML. CODEBASE permite especificar un URL para los ficheros del cdigo y dems
elementos del applet. Si el directorio ddado en el URL de CODEBASE es relativo, se interpreta respecto al
directorio del HTML; si es absoluto puede ser cualquiera.
Si un applet consta de varias clases, cada fichero .class requiere una conexin con el servidor web, lo que
puede tardar. En este caso conviene agrupar los ficheros en un archivo comprimido que se cargue en una
sola conexin. Los archivos JAR, basados en los ZIP, pueden crearse con el programa jar del JDK, en la
forma jar cvf File.jar *.class *.gif. El ejemplo creara un fichero File.jar con todos los ficheros *.class y *.gif
del directorio actual. Si las clases pertenecieran a un package llamado es.mad.inf se usara el comando: jar
cvf File.jar es\mad\inf\*.class *.gif
La comunicacin entre el applet y navegador en que se ejecuta se puede controlar con la interface
AppletContext (package java.applet). El navegador implementa el interface, cuyos mtodos puede usar el
applet para obtener informacin y realizar operaciones como mostrar mensajes en la barra de estado. La
barra de estado es compartida por navegador y applets, con la precaucin que el mensaje sea sobreescrito
por el navegador u otras applets y el usuario no llegue a verlo. Los mensajes breves de la barra de estado
se generan con el mtodo showStatus. Ejemplo:
getAppletContext().showStatus("Cargado del fichero " + filename);
Los mensajes importantes se deben dirigir a la salida estndar o a la de errores. Se pueden enviar con las
sentencias System.out.print, System.out.println, System.error.print o System.error.println().
Para mostrar documentos HTML en una ventana del navegador se pueden usar los mtodos
showDocument(URL miUrl, [String target]), que muestra un documento HTML en el frame del navegador
que indica target (name, _top, _parent, _blank, _self) o showDocument(URL miUrl), que muestra un
documento HTML en la ventana actual del browser.
Un applet puede obtener informacin de otras applets en ejecucin en la misma pgina del navegador,
enviarles mensajes y ejecutar sus mtodos. El mensaje se enva invocando los mtodos del otro applet con
sus argumentos. Algunos navegadores, para que las applets se puedan comunicar, obligan a que
provengan del mismo navegador o del mismo directorio (mismo codebase).
Para obtener informacin de otras applets se pueden usar los mtodos getApplet(String name), que
devuelve el applet llamado name (null si no la encuentra) o getApplets, que devuelve una enumeracin con
todas las applets de la pgina.
Para usar los mtodos de un applet en ejecucin en la misma pgina HTML, debe hacerse un cast del
objeto de la clase Applet obtenido como retorno de getApplet a la clase concreta. Para que pueda haber
respuesta (comunicacin en ambos sentidos), el primer applet que enva un mensaje debe enviar una
referencia a s mismo con el argumento this.

Programacin en Java 74
7.3. Imagen y sonido en applets
La clase Applet y el interface AudioClips permiten usar sonidos en applets. La tabla muestra algunos
mtodos al respecto. En general conviene cargar los sonidos en un thread distinto (creado en el mtodo init)
que en el propio mtodo init, que tardara ms. Si el sonido no ha terminado de cargarse (en el thread para
ello) y se interacciona con el applet para ejecutarlo, se puede avisar de que no se ha terminado de cargar.
Mtodos de Applet Funcin
public AudioClip getAudioClip(URL url) Devuelve el objeto especificado por url, que
implementa la interface AudioClip
public AudioClip getAudioClip(URL url, String name) Devuelve el objeto especificado por url (direccin
base) y name (direccin relativa)
play(URL url), play(URL url, String name) Hace que suene el AudioClip de la direccin dada
Mtodos del interface AudioClip (en java.applet) Funcin
void loop() Ejecuta el sonido repetidamente
void play() Ejecuta el sonido una sola vez
void stop() Detiene el sonido
Los applets admiten ficheros del servidor en formato jpeg y gif. Se pueden cargar con el mtodo getImage
de Applet, en las formas public Image getImage(URL url) o public Image getImage(URL url, String name).
Estos mtodos devuelven el control inmediatamente. Las imgenes se cargan al dar la orden de dibujarlas
en pantalla. El dibujo se realiza de forma incremental, a medida que el contenido llega. Para dibujar
imgenes se usa el mtodo drawImage de la clase Graphics, en las formas:
public abstract boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer)
public abstract boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor, ImageObserver
observer)
El primero dibuja la imagen con su tamao natural; el segundo realiza un cambio de escala. Los mtodos
drawImage van dibujando la parte de la imagen que llega, con su tamao, a partir de las coordenadas (x, y)
indicadas, usando bgcolor para pixels transparentes. Devuelven el control inmediatamente, aunque la
imagen no est cargada del todo, caso en que se devuelve false. En cuanto se carga una parte adicional de
la imagen, el proceso que realiza el dibujo avisa al ImageObserver especificado, una interface de Applet que
permite seguir el proceso de carga de una imagen.
7.4. Obtencin de las propiedades del sistema y uso de threads
Un applet puede obtener la informacin del sistema o el entorno en que se ejecuta que sea accesible. Para
acceder a las propiedades del sistema se usa un mtodo static de la clase System: String salida =
System.getProperty("file.separator"). No se puede acceder a las propiedades del sistema: "java.class.path",
"java.home", "user.dir", "user.home", "user.name". Las propiedades del sistema accesibles son :
Mtodo Significado de la propiedad del Mtodo Significado de la propiedad
sistema del sistema
file.separator Separador de directorios (por java.class.version Nmero de version de las
ejemplo, "/" o "\") clases de Java
java.vendor Nombre especfico del proveedor path.separator Separador en la variable Path
Java (por ejemplo, ":"
java.vendor.url URL del proveedor Java java.version Nmero de versin Java
line.separator Separador de lneas os.arch Arquitectura del SO
os.name Nombre del sistema operativo
Un applet puede ejecutarse con varios threads. As, en las que se ejecutan los mtodos mayores (init, start,
stop y destroy) dependen del navegador o el entorno de ejecucin. Los mtodos grficos (paint, update y
repaint) se ejecutan siempre desde un thread especial del AWT.
Algunos navegadores dedican un thread para cada applet en una misma pgina; otros crean un grupo de
para cada applet (para poderlas matar al tiempo, por ejemplo). En cualquier caso se garantiza que todos los
threads creadas por mtodos mayores pertenecen al mismo grupo.

Programacin en Java 75
Se deben introducir threads en applets siempre que haya tareas pesadas, que si se incluyen en el init
bloquean la actividad del applet o la pgina html. Las tareas pesadas pueden ser de 2 tipos, las que slo se
hacen una vez y las que se repiten. Un ejemplo de tarea que se repite puede ser una animacin. La tarea se
pone en un bucle del thread, que debera crearse en el mtodo start del applet y destruirse en stop. As
cuando el applet no est visible se dejan de consumir recursos. Al crear el thread en el mtodo start se pasa
una referencia al applet con this. El applet debe implementar la interface Runnable y por tanto definir el
mtodo run, que es el centro del Thread.
Un ejemplo de tarea que se realiza una sola vez es la carga de imgenes *.gif o *.jpeg en un thread
especial. Pero los sonidos no se cargan en threads de forma automtica; se deben crear. Es un caso tpico
de programa producer-consumer: el thread es producer y el applet consumer. Los threads deben estar
sincronizados, para lo que se usan los mtodos wait y notifyAll.
En el ejemplo de la derecha un thread con tarea repetitiva muestra como el mtodo run se detendr en
cuanto se ejecute el mtodo stop, porque la referencia al thread est a null.
public void start() { public class MiApplet extends Applet {
if (repetitiveThread == null) { ...
repetitiveThread = new Thread(this); // lo crea public void init() {...}
} ...
repetitiveThread.start(); // arranca: start llama a // clase para cerrar la aplicacin
run
static class WL extends WindowsAdapter {
}
public void windowClosing(WindowEvent e) {
public void stop() {
MiApplet.stop();
repetitiveThread = null; // para la ejecucin
MiApplet.destroy();
}
System.exit(0);
public void run() {
}
...
} // fin de WindowAdapter
while (Thread.currentThread() ==
public static void main(String[] args) {
repetitiveThread) {
static MiApplet unApplet = new MiApplet();
... // tarea repetitiva.
Frame unFrame = new Frame("MiApplet");
}
unFrame.addWindowListener(new WL());
}
unFrame.add(unapplet, BorderLayout.CENTER);
Es interesante desarrollar aplicaciones que
puedan funcionar como applets y viceversa. En unFrame.setSize(400,400);
concreto, para que un applet se ejecute como
unApplet.init();
aplicacin pueden seguirse los pasos:
unApplet.start();
1. Aadir un mtodo main a la clase MiApplet
unFrame.setVisible(true);
2. Que el main cree un objeto de la clase
MiApplet e introducirlo en un Frame }
3. Que el main haga lo que hara el navegador: } // fin de la clase MiApplet
llamar a init y start de MiApplet.
4. Se puede aadir tambin una static inner class derivada de WindowAdapter que gestione el evento de
cerrar la ventana de la aplicacin definiendo el mtodo windowClosing. Este mtodo llama a System.exit(0).
Segn como sea el applet, el mtodo windowClosing previamente debe llamar a MiApplet.stop y
MiApplet.destroy, lo que para applets hace el navegador. En este caso conviene que el objeto de MiApplet
creado por main sea static, en lugar de variable local. A la izquierda se ha presentado un ejemplo.

Programacin en Java 76
8. EXCEPCIONES
Java incorpora gestin de errores. En general, los errores sintcticos se detectan en compilacin y el resto
(semnticos) en ejecucin. En Java una Exception es un tipo de error producido en ejecucin. Algunas
excepciones son fatales; provocan el fin del programa, que conviene terminar ordenadamente y avisar del
tipo de error dado. Otras, como no encontrar un fichero, pueden ser tratadas, sin traumas.
Un buen programa debe gestionar la mayor cantidad
posible de errores. Se distinguen 2 formas de hacerlo.
Tradicional. Se devuelve un cdigo de error, fruto de la
comprobacin del entorno que ha llamado al mtodo y
gestionando el resultado correcto o cada posible error.
Es complicado cuando hay varios niveles de llamadas
a mtodos.
Con soporte del lenguaje. Consiste en usar los
recursos nativos del lenguaje para gestionar errores.
Es lo habitual en lenguajes como C++, VB y Java.
Las excepciones estndar de java representan los errores con 2 tipos de clases derivadas de Throwable,
Error y Exception. La figura muestra parcialmente su jerarqua de clases. La clase Error se refiere a errores
de compilacin, sistema o JVM. Suelen ser irrecuperables, no dependen del programador ni los gestiona.
La clase Exception distingue RuntimeException, excepciones implcitas debidas a la programacin. El resto
de clases derivadas de Exception son excepciones explcitas, que Java obliga a su gestin.
En el caso de RuntimeException, Java chequea y lanza automticamente las excepciones durante la
ejecucin. No se necesita establecer bloques try/catch. Representan 2 casos de errores de programacin:
los que no suelen comprobarse (p.ej. recibir una referencia null en un mtodo) y los que debieran
comprobarse (p.ej. sobrepasar el tamao asignado a un array).
La razn de no comprobar estos tipos de errores, es la complicacin que supone para el texto del cdigo.
Las clases derivadas de Exception pueden pertenecer a distintos packages de Java: java.lang (Throwable,
Exception); java.io (EOFException...) u otros. Por heredar de Throwable los tipos de excepciones pueden
usar los mtodos String getMessage (extrae el mensaje asociado con la excepcin), String toString
(devuelve un String que describe la excepcin) y void printStackTrace (indica el mtodo donde se lanz).
8.1. Lanzamiento y captura de excepciones
Al darse una situacin anmala es necesario lanzar una excepcin. El proceso consiste en crear un objeto
Exception de la clase adecuada y lanzar la excepcin con throw seguido del objeto Exception creado.
En el cdigo de ejemplo la excepcin // Cdigo que lanza la excepcin MyException al detectar el error
debe capturarse (catch) y gestionarse
MyException me = new MyException("MyException message");
en el mtodo o en otro lugar del
programa (p.ej. un mtodo anterior). throw me;
Al lanzar una excepcin el mtodo termina sin devolver ningn valor. Slo en caso que el mtodo incluya los
bloques try/catch/finally se ejecutar el bloque catch o finally. Todo mtodo en que se produzcan uno o ms
tipos de excepciones (y que no use directamente try/catch/finally) debe declararlas en el encabezamiento de
la funcin con la palabra throws. Si un mtodo puede lanzar varias excepciones, se ponen detrs de throws
separadas por comas, en la forma de la primera lnea.
public void leerFichero(String fich) throws EOFException, FileNotFoundException {}
public void leerFichero(String fich) throws IOException {}
La segunda lnea especifica slo una superclase de excepciones indicando que pueden lanzarse
excepciones de cualquiera de sus clases derivadas. Las excepciones pueden ser lanzadas por leerFichero
o algn mtodo que l llame, ya que las clases EOFException y FileNotFoundException derivan de
IOException.
Ciertos mtodos de packages y algunos creados producen excepciones. Si el usuario los llama sin tratarlas
se produce un error de compilacin y un mensaje tipo: Exception java.io.IOException must be caugth. El
programa no compilar si el usuario no gestiona la excepcin con un bloque try-catch o relance la excepcin
con throws en la cabecera del mtodo. El compilador obliga a capturar las excepciones explcitas, aunque
no se traten. Es conveniente al menos indicar un mensaje con el tipo de excepcin producida.
Para excepciones que no pertenecen a las void metodo1(){
RuntimeException, que hay que gestionar, deben
...
Programacin en Java 77
usarse los bloques try, catch y finally. El cdigo
try { // Cdigo que puede lanzar las excepciones
del bloque try est controlado. Al darse una
excepcin el control salta o sale del try y pasa al } catch (IOException e1) { // Gestiona IOException
catch. Se pueden incluir tantos catch como sean
System.out.println(e1.getMessage());
necesarios. Cada uno trata un tipo de excepcin.
Las excepciones se pueden capturar en grupo } catch (MyException e2) { // Gestiona MyException
con una superclase de la que deriven todas, o
individualmente. System.out.println(e2.getMessage()); return;

El bloque finally es opcional. Si se incluye sus } finally { // Se ejecuta siempre


sentencias se ejecutan siempre, sea cual sea la ...
excepcin y se produzca o no. Se ejecuta aunque
en el try haya un continue, break o return. El } // Fin try
ejemplo a la derecha presenta un mtodo que ...
controla una IOException de lectura de ficheros y
una MyException dada. } // Fin metodo1

En casos en que el cdigo de un mtodo genere una Exception y no se desee incluir su gestin, Java
permite que el mtodo la pase o relance al mtodo que lo llam, sin incluir try/catch. Esto se consigue con la
adicin de throws ms el nombre de la excepcin concreta tras la lista de argumentos del mtodo. El
mtodo llamante debe incluir los bloques try/catch o pasar tambin la excepcin.
As, se puede pasar la bola de un mtodo a otro void metodo2() throws IOException, MyException {
hasta el ltimo, el main. El ejemplo anterior
...
realizaba la gestin de las excepciones en el
propio mtodo. En el cdigo del metodo2 se } // Fin del metodo2
relanzan las excepciones.
Si un mtodo llama a otros que pueden lanzar excepciones (p. ej. de un package de Java), puede capturar
las posibles excepciones y gestionarlas o desentenderse y remitirlas a otro mtodo anterior en la pila. Si no
hace ninguna de las 2 cosas el compilador da un error, salvo que se trate de una RuntimeException.
El bloque finally debe ir tras los bloques catch. La try {
forma general de una seccin donde se controlan
// Cdigo que puede lanzar excepcin tipo A, B o C
las excepciones es la mostrada en el cuadro.
Finally es til en casos en que se necesite } catch (A a1) { // Gestiona la excepcin A
recuperar o devolver a su situacin original un
} catch (B b1) { // Gestiona la excepcin B
elemento. No es liberar la memoria; eso lo hace
el garbage collector. Se puede pensar un bloque } catch (C c1) { // Gestiona la excepcin C
try en que se abre un fichero para R/W de datos y
se cierra. El fichero abierto se debe cerrar tanto si } finally { // Sentencias que se ejecutan siempre
se produce una excepcin como si no. }
De otro modo pueden darse problemas futuros. As, se incluyen las sentencias de cierre en el bloque finally.
8.2. Creacin de nuevas excepciones y trato con herencia
Se pueden crear excepciones heredando de la class MiExcepcion extends Exception {
clase Exception o una de sus clases derivadas,
public MiExcepcion() { // Constructor por defecto
eligiendo la que mejor se adapte al tipo de
excepcin a definir. Las clases Exception suelen super();
tener 2 constructores, uno sin argumentos y otro
que recibe un String, en el que se suele definir un }
mensaje explicativo del tipo de excepcin. public MiExcepcin(String s) { // Con mensaje
Conviene que el constructor llame al de la clase super(s);
de la que deriva super(String). Al ser clases como
otras, se podran incluir variables y mtodos }
nuevos, como en el ejemplo del cdigo. }
Si un mtodo redefine otro de una superclase que usa throws, no tiene obligatoriamente que poder lanzar
todas las mismas excepciones de la clase superior. Podr lanzar las mismas o menos, pero no ms.
Tampoco podr lanzar nuevas excepciones ni excepciones de una clase ms general. Es una restriccin til
ya que el cdigo que funciona con la clase base podr trabajar de forma automtica con referencias de
clases derivadas, incluyendo el trato de excepciones.

Programacin en Java 78
9. ENTRADA/SALIDA DE DATOS
La manera de representar e/s en Java 1.1 es con streams (flujos de datos); conexiones entre el programa y
el origen o destino de los datos. La informacin se trasmite en serie a travs del stream. Esto supone una
forma general de representar distintos tipos de comunicacin.
Por ejemplo, al imprimir algo en pantalla, se usa un
stream que conecta el monitor al programa. Se
pasa al stream la orden de escribir y ste lo
muestra en pantalla. O para comunicaciones a
travs de Internet o la lectura de datos del puerto
en serie.
Las clases para la comunicacin del programa con
el entorno se disponen en el package java.io. En el
package existen 2 familias de jerarquas para E/S.
La diferencia estriba en que una opera con bytes y
la otra con caracteres (formados por 2 bytes al
usar Unicode). La estructura general es que para
un fin (entrada o salida) hay 2 clases que manejan
bytes y otras 2 que manejan caracteres.
Desde Java 1.0, la E/S de datos se poda hacer
con clases derivadas de InputStream (para lectura)
y OutputStream (para escritura). La figura muestra
sus clases derivadas.
Estas clases tienen los mtodos bsicos read y write que manejan bytes y que no se suelen usar
directamente. En Java 1.1 aparecieron 2 nuevas familias de clases, derivadas de Reader y Writer, que
manejan caracteres en vez de bytes y que resultan ms prcticas para las aplicaciones en las que se
maneja texto. Las clases que heredan de Reader y Writer se incluyen en la siguiente figura.

Las clases con fondo gris definen de dnde o a dnde se envian datos; el dispositivo con que conecta el
stream. Las de fondo blanco aaden caractersticas particulares a la forma de enviarlos. La intencin es que
se combinen para obtener el comportamiento deseado.
Por ejemplo: BufferedReader in = new BufferedReader(new FileReader("autoexec.bat")); crea un stream
que permite leer del archivo autoexec.bat. A partir de l se crea un objeto BufferedReader (que usa buffer).
Los caracteres que lleguen a travs del FileReader pasan a travs del BufferedReader; usan el buffer. Al
definir una comunicacin con un dispositivo siempre se comienza indicando origen o destino de la
comunicacin (clases en gris) y luego se aaden caractersticas (clases en blanco).
Se recomienda usar siempre que sea posible las clases Reader y Writer, dejando InputStream y
OutputStream para casos imprescindibles como la serializacin y compresin.
9.1. Nomenclatura de las clases de java.io
Las clases java.io siguen Palabra Significado
una nomenclatura
InputStream, OutputStream Lectura/Escritura de bytes
sistemtica para expresar
su funcin a partir del Reader, Writer Lectura/Escritura de caracteres
nombre. Se presentan en
File Archivos

Programacin en Java 79
la tabla.
String, CharArray, ByteArray, Memoria (a travs del tipo primitivo
Al leer un dato del disco se StringBuffer indicado)
lleva a memoria junto a los
Piped Tubo de datos
datos contiguos, de modo
que la siguiente vez que se Buffered Buffer
lea la probabilidad de que
est en memoria se eleva. Filter Filtro
Para escritura lo mismo, Data Intercambio de datos en formato
intentando realizar en una propio de Java
sola operacin de escritura
fsica varias sentencias Object Persistencia de objetos
individuales de escritura. Print Imprimir
La siguiente tabla muestra el uso de las clases que definen el lugar con que conecta el stream.
Clases Funcin que realizan
FileReader, FileWriter, FileInputStream y Leen y escriben en archivos de disco
FileOutputStream
StringReader, StringWriter, CharArrayReader, Se comunican con la memoria principal. En vez de
CharArrayWriter, ByteArrayInputStream, acceder de modo habitual al contenido, p. ej. de un String,
ByteArrayOutputStream, lo leen carcter a carcter. tiles al usar un modo
StringBufferInputStream estndar de gestionar los dispositivos con un programa
PipedReader, PipedWriter, PipedInputStream, Se usan como un tubo o conexin bilateral. P. ej., en un
PipedOutputStream programa con dos threads permiten la comunicacin entre
ellos. Un thread tiene el objeto PipedReader y el otro
PipedWriter. Si los streams estn conectados, lo que se
escriba en el PipedWriter queda disponible para leerse del
PipedReader. Tamben puede comunicar 2 programas
La siguiente tabla muestra clases que aaden caractersticas al comportamiento de un stream definido.
Clases Funcin que realizan
BufferedReader, BufferedWriter, Aaden un buffer al manejo de datos. Se reducen las operaciones
BufferedInputStream, directas sobre el dispositivo, por eficiencia. BufferedReader p. ej.
BufferedOutputStream dispone el mtodo readLine que lee una lnea y la devuelve como
String
InputStreamReader, Clases puente que permiten convertir streams que usan bytes en
OutputStreamWriter otros que manejan caracteres. Son la nica relacin entre ambas
jerarquas. No existen clases que realicen la transformacin
inversa
ObjectInputStream, Pertenecen al mecanismo de serializacin
ObjectOutputStream
FilterReader, FilterWriter, Clases base para aplicar filtros o procesos al stream de datos. Se
FilterInputStream, FilterOutputStream podran extender para comportamientos a medida
DataInputStream, DataOutputStream Se usan para escribir y leer datos directamente en los formatos
propios de Java. Los convierten en algo ilegible , independiente
de la plataforma. Se usan por tanto para almacenamiento o
transmisiones entre mquinas con funcionamiento distinto
PrintWriter, PrintStream Tienen mtodos adaptados para imprimir las variables de Java
con la apariencia normal. A partir de un boolean escriben true o
false, colocan la coma de un nmero decimal, etc.
9.2 E/S estndar
En Java, la entrada de teclado y la salida a pantalla se regulan con la clase System, del package java.lang.
Agrupa mtodos y objetos en relacin con el sistema local. Contiene, entre otros, tres objetos static:
System.in Objeto de la clase InputStream preparado para recibir datos desde la entrada estndar
System.out Objeto de la clase PrintStream que imprimir los datos en la salida estndar del sistema

Programacin en Java 80
System.err Objeto de la clase PrintStream. Usado para mensajes de error que por defecto se muestran
por pantalla
Estas clases permiten la comunicacin alfanumrica con el programa a travs de los mtodos de la
siguiente tabla. Permiten la E/S a nivel muy elemental.
Mtodos de System.in Funcin que realizan
int read() Lee un carcter y lo devuelve como int
Mtodos de System.out y System.err Funcin que realizan
int print(cualquier tipo) Imprime en pantalla el argumento que se le pase. Puede recibir
cualquier tipo primitivo de variable de Java.
int println(cualquier tipo) Como el anterior, aadiendo '\n' (nueva lnea) al final
Existen 3 mtodos de System que permiten sustituir la E/S estndar. P. ej. para hacer que el programa lea
de un archivo y no del teclado: System.setIn(InputStream is); System.setOut(PrintStream ps); y
System.setErr(PrintStream ps);
El argumento de setIn no tiene que ser necesariamente de tipo InputStream. Es una referencia a la clase
base, y por tanto puede apuntar a objetos de cualquier clase derivadas (como FileInputStream). El
constructor de PrintStream acepta un OutputStream, luego se puede dirigir la salida estndar a cualquier
clase definidas para salida.
Si se usan estas sentencias con un compilador Java 1.1 se obtiene un mensaje de mtodo obsoleto
(deprecated) al crear un objeto PrintStream. Esto pretenda generalizar el uso de PrintWriter, pero existen
casos en los que es imprescindible un elemento PrintStream. Java 1.2 vuelve a admitirlo.
9.2.1. Salida de texto y variables por pantalla
Para imprimir en pantalla se usan los mtodos System.out.print y System.out.println. Sus caractersticas:
1. Pueden imprimir valores escritos directamente en el cdigo System.out.println("Hola, Mundo!");
o cualquier tipo de variable primitiva de Java
System.out.println(57);
2. Se pueden imprimir varias variables en una llamada con el
double numeroPI = 3.141592654;
operador + (concatenacin). Equivale a convertir a String las
variables que no lo sean y concatenar las cadenas de System.out.println(numeroPI);
caracteres (el primer argumento debe ser String):
String hola = new String("Hola");
System.out.println("Hola, Mundo! " + numeroPI);
System.out.println(hola);
Los objetos System.out y System.err son de clase PrintStream. Aunque imprimen las variables de modo
legible, no permiten dar a la salida un formato distinto al disponible por defecto, un formato a medida.
9.2.2. Lectura del teclado
Para leer de teclado se puede usar el mtodo System.in.read de clase InputStream, que lee un carcter en
cada llamada. Su valor de retorno es entero. Si se espera otro tipo hay que hacer una conversin explcita
mediante un cast. System.in.read puede lanzar la excepcin java.io.IOException que obliga a definirla.
Como en el cdigo de la izquierda.
char c;
try { String frase = new String("");
c=(char)System.in.read(); try {
} while((c=System.in.read()) != '\n')
catch(java.io.IOException ioex) { frase = frase + c; // frase.append(c);
// operaciones para la excepcin }
}
catch(java.io.IOException ioex) {}
Para leer datos ms largos que un carcter es necesario un bucle while o for y concatenar los caracteres.
Por ejemplo, para leer una lnea se podra usar un bucle while guardando los caracteres ledos en un String
o en un StringBuffer (ms rpido que String), como se muestra en el cdigo de la derecha. Una vez leida
una lnea, sta puede contener nmeros de coma flotante, etc. Pero hay una manera ms fcil de
conseguirlo, usando la biblioteca java.io.

Programacin en Java 81
Para facilitar la lectura de teclado se puede leer una lnea entera con una instruccin usando un objeto
BufferedReader. El mtodo String readLine de BufferReader lee todos los caracteres hasta encontrar un '\n'
o '\r' y los devuelve como String (sin incluir '\n' ni '\r'). String readLine puede lanzar java.io.IOException.
System.in es un objeto de clase InputStream y BufferedReader pide un Reader en el constructor. La
relacin entre ambos es InputStreamReader, que acepta un InputStream como argumento del constructor y
es clase derivada de Reader.
Por tanto si se desea leer una lnea InputStreamReader isr = new InputStreamReader(System.in);
completa desde la entrada estndar se
BufferedReader br = new BufferedReader(isr);
podr usar el cdigo de la derecha, que
lee una lnea completa del teclado. String frase = br.readLine(); // Se lee la lnea con una llamada
El thread que ejecute este cdigo se para en esta lnea hasta que el usuario termine la lnea (intro). Para
manejar una lnea entera, la clase java.util.StringTokenizer posibilita separar una cadena de carcteres en
las palabras (tokens) que la forman, conjuntos de caracteres separados por espacio, '\t', '\r', o por '\n'.
Asimismo, cuando se precise se convertirn los tokens en nmeros. La tabla muestra algunos mtodos de
la clase StringTokenizer.
Mtodos Funcin que realizan
StringTokenizer(String) Constructor a partir de la cadena que hay que separar
boolean hasMoreTokens() Hay ms palabras disponibles en la cadena?
String nextToken() Devuelve el siguiente token de la cadena
int countTokens() Devuelve el nmero de tokens que se pueden extraer de la frase
La clase StreamTokenizer de java.io aporta ms posibilidades que StringTokenizer, pero es ms compleja.
Separa en tokens lo que entra en un InputStream o Reader. Para convertir un String del tipo 3.141592654
en el valor double correspondiente se crea un objeto Double a partir de l y luego se extrae su valor double:
double pi = (Double.valueOf("3.141592654")).doubleValue();
El uso de estas clases facilita el acceso desde teclado, resultando un cdigo ms legible. Adems tiene la
ventaja de que se puede generalizar a la lectura de archivos.
9.3. Lectura y escritura de archivos
El manejo de archivos sigue el esquema de la E/S estndar. Java dispone las clases FileInputStream y
FileOutputStream para leer y escribir bytes en archivos. En archivos de texto son preferibles FileReader y
FileWriter. Se puede construir un objeto de cualquiera de estas clase a partir de un String con el nombre o
direccin en disco del archivo o con un objeto de la clase File que lo represente.
El cdigo de la derecha muestra un ejemplo. Si no se FileReader fr1 = new FileReader("archivo.txt");
encuentra el archivo indicado, los constructores de
// es equivalente a:
FileReader y FileInputStream pueden lanzar la
excepcin java.io.FileNotFoundException. Los File f = new File("archivo.txt");
constructores de FileWriter y FileOutputStream pueden
FileReader fr2 = new FileReader(f);
lanzar java.io.IOException.
Si no se encuentra el archivo indicado se crea. Por defecto, las 2 clases escriben al inicio del archivo. Para
escribir detrs del ltimo registro (append), se usa un segundo argumento de tipo boolean con valor true:
FileWriter fw = new FileWriter("archivo.txt", true).
9.3.1. Clases file y filedialog
Un objeto de la clase File puede representar un archivo o un directorio. Tiene los constructors de la derecha.
File(String name) File f1 = new File("c:\\windows\\notepad.exe"); // La barra '\' se escribe '\\'
File(String dir, String name) File f2 = new File("c:\\windows"); // Un directorio
File(File dir, String name). File f3 = new File(f2, "notepad.exe"); // Es igual a f1
Se puede indicar el nombre de un archivo, nombre y directorio o slo el directorio, como path absoluto y
relativo al directorio actual. Para saber si el archivo existe se puede llamar al mtodo boolean exists(). Los
mtodos de la siguiente tabla informan de las caractersticas del fichero o directorio y en su caso los
mtodos para recuperar el path del archivo.

Programacin en Java 82
Mtodos Funcin que realizan Mtodos Funcin que realizan
boolean isFile() True si el archivo existe boolean isDirectory() True si existe el directorio
long length() Tamao del archivo en B mkdir() Crea directorio
long lastModified() Fecha ltima modificacin String[] list() Lista archivos del directorio
boolean canRead() True si se puede leer String getPath() Path del objeto File
boolean canWrite() True si se puede escribir String getName() Nombre del archivo
delete() Borrar archivo / directorio String getAbsolutePath() Path absoluto
RenameTo(File) Cambiar el nombre String getParent() Devuelve el directorio padre
Para preguntar por un archivo, tpicamente se usa una caja de dilogo. La clase java.awt.FileDialog la
presenta segn cada SO para guardar o abrir ficheros. Sus constructores son los de la derecha.
Type puede ser FileDialog.LOAD o FileDialog.SAVE segn la FileDialog(Frame fr)
operacin a realizar. Es fcil conectar este dilogo con un File,
FileDialog(Frame fr, String title)
con los mtodos String getFile y String getDirectory. P. ej.:
FileDialog(Frame fr, String title, int type)
FileDialog fd = new FileDialog(f, "Elija un archivo");
fd.show();
File f = new File(fd.getDirectory(), fd.getFile());
9.3.2. Lectura y escritura de archivos de texto
Se puede crear un objeto BufferedReader para leer de un archivo de texto en la forma:
BufferedReader br = new BufferedReader(new FileReader("archivo.txt"));
Con el objeto de tipo BufferedReader se puede conseguir lo mismo que con el mtodo readLine y la clase
StringTokenizer. En caso de archivos es importante usar el buffer porque escribir en disco es lento y leer
directamente y no de uno en uno hace ms eficiente el acceso. Es el ejemplo de la izquierda.
// Lee un archivo entero como con el teclado try {
String texto = new String(); FileWriter fw = new FileWriter("escribeme.txt");
try { BufferedWriter bw = new BufferedWriter(fw);
FileReader fr = new FileReader("archivo.txt"); PrintWriter salida = new PrintWriter(bw);
entrada = new BufferedReader(fr); salida.println("Esta es la primera lnea");
String s; salida.close();
while((s = entrada.readLine()) != null) bw = new BufferedWriter(new FileWriter("escribeme.txt",
true)); // Modo append
texto += s;
salida = new PrintWriter(bw);
entrada.close();
salida.print("Y esta la segunda. ");
}
double b = 123.45;
catch(java.io.FileNotFoundException fnfex) {
salida.println(b);
System.out.println("File not found: " + fnfex);}
salida.close();
catch(java.io.IOException ioex) {}
}
cacth(java.io.IOException ioex) { }
La clase PrintWriter es ms prctica para escribir un archivo de texto. Dispone los mtodos print y println,
idnticos a los de System.out de PrintStream. Un objeto PrintWriter se puede crear a partir de un
BufferedWriter (para disponer de buffer), que se crea a partir del FileWriter al que se pasa el nombre del
archivo. As, escribir en el archivo es tan fcil como en pantalla. El de la izquierda es un ejemplo de uso.
9.3.3. Archivos no de texto
DataInputStream y DataOutputStream son // Escritura de una variable double
clases de Java 1.0 no alteradas. Para leer y
DataOutputStream dos = new DataOutputStream(

Programacin en Java 83
escribir datos primitivos directamente (sin
new BufferedOutputStream(
convertir a String) siguen siendo ms tiles.
new FileOutputStream("prueba.dat")));
Son clases diseadas para trabajar de
manera conjunta. Una puede leer lo que la double d1 = 17/7;
otra escribe, como una secuencia de bytes.
dos.writeDouble(d1);
Se usan para guardar datos de forma
dos.close();
independiente de la plataforma (o enviarse
por red entre mquinas de distinta // Lectura de la variable double
naturaleza).
DataInputStream dis = new DataInputStream(
Pero obligan a usar clases hijas de
InputStream y OutputStream y por tanto ms new BufferedInputStream(
complicadas de usar. El cdigo del ejemplo new FileInputStream("prueba.dat")));
primero escribe en el fichero prueba.dat y
despus lee los datos. double d2 = dis.readDouble();

9.4 Serializacin
Es el proceso por el que un objeto se puede convertir a secuencia de bytes, permitiendo, en el futuro,
reconstruirlo. Esto es til para guardar un objeto en un archivo o enviarlo por red. Para que una clase use la
serializacin, debe implementar la interface Serializable, que no define mtodos. Casi todas las clases
estndar de Java son serializables. Una clase podra serializarse declarndola como en el prototipo.
public class [nombre de la clase] implements Serializable { }
Para escribir y leer objetos se usan las clases ObjectInputStream y ObjectOutputStream, que cuentan con
los mtodos writeObject() y readObject(). Por ejemplo:
Debe tenerse en cuenta que readObject ObjectOutputStream objout = new ObjectOutputStream(
devuelve un Object sobre el que se har un
new FileOutputStream("archivo.x"));
casting para que el objeto sea til. La
reconstruccin necesita que el archivo *.class String s = new String("Me van a serializar");
est al alcance del programa.
objout.writeObject(s);
Al serializar un objeto, automticamente se
serializan sus variables y objetos miembro. A su ObjectInputStream objin = new ObjectInputStream(
vez se serializan los que esos objetos miembro new FileInputStream("archivo.x"));
puedan tener (todos deben ser serializables).
Tambin se reconstruyen de igual manera. String s2 = (String) objin.readObject();

Si se serializa un Vector con varios Strings, todo se convierte en una serie de bytes. Al recuperarlo la
reconstruccin deja todo en el lugar en que se guard. Si 2 objetos contienen una referencia a otro, ste no
se duplica si se escriben o leen ambos del mismo stream. Es decir, si el mismo String est contenido 2
veces en el Vector, slo se guardara una vez y al recuperarlo slo se creara un objeto con 2 referencias en
el vector.
Aunque la serializacin es automtica, puede especificarse cmo hacer las cosas. La palabra clave
transient permite indicar que un objeto o variable miembro no sea serializada con el resto del objeto. Al
recuperarlo, lo que est marcado como transient ser 0, null o false (no se llama a ningn constructor) hasta
que se le d un nuevo valor. Es el tpico caso de una password que no se guarda por seguridad.
Las variables y objetos static no son serializados. Para ello hay que escribir el cdigo. P. ej. programar un
mtodo que serialice objetos estticos al que se llamar tras serializar el resto de elementos. As, habra
que recuperarlos explcitamente tras recuperar el resto de objetos. Las clases que implementan Serializable
pueden definir 2 mtodos con los que controlar la serializacin. No estn obligadas porque estos mtodos
obtiene directamente el comportamiento por defecto. Si se definen sern los que se usen al serializar.
private void writeObject(ObjectOutputStream stream) throws IOException
private void readObject(ObjectInputStream stream) throws IOException
El primero permite indicar qu se escribe o aadir otras static double g = 9.8;
instrucciones al comportamiento por defecto.
private void writeObject(ObjectOutputStream
El segundo debe poder leer lo que escribe writeObject. stream) throws IOException {
Puede usarse para poner al da las variables que lo
stream.defaultWriteObject();
necesiten al ser recuperado un objeto. Hay que leer en el
orden en que se escriben los objetos. stream.writeDouble(g);

Programacin en Java 84
Se puede obtener el comportamiento por defecto en los }
mtodos llamando a stream.defaultWriteObject y
private void readObject(ObjectInputStream
stream.defaultReadObject.
stream) throws IOException {
Para guardar explcitamente los tipos primitivos se
stream.defaultReadObject();
pueden usar los mtodos de ObjectInputStream y
ObjectOutputStream, idnticos a los de DataInputStream g = stream.readDouble(g);
y DataOutputStream (writeInt, readDouble...) o guardar
objetos de sus clases equivalentes (Integer, Double...). }

Por ejemplo, si en una clase llamada Tierra se necesita que al serializar un objeto siempre le acompae la
constante g (9,8) definida static el cdigo podra ser el siguiente.
La interface Externalizable extiende interface Externalizable {
Serializable, con el mismo objetivo,
public void writeExternal(ObjectOutput out) throws IOException;
pero sin comportamiento automtico,
debe programarse. Presenta 2 public void readExternal(ObjectInput in) throws IOException,
mtodos a implementar. Cuando se
transforma un objeto, writeExternal es ClassNotFoundException;
responsable de lo que se hace. }
Slo se guardar lo que se indique en el mtodo. El mtodo readExternal debe ser capaz de recuperar lo
guardado por writeExternal. La lectura debe ser en el mismo orden que la escritura. Debe saberse que
antes de llamar a este mtodo se llama al constructor por defecto de la clase.
9.5. Lectura de un archivo en un servidor de Internet
Con la direccin de Internet de un //Lectura del archivo (texto HTML)
archivo, la biblioteca Java
URL direccion = new URL("http://www1.ceit.es/subdir/MiPagina.htm");
permite leerlo con un stream.
String s = new String();
Es una aplicacin sencilla que
muestra la polivalencia del String html = new String();
concepto de stream. En el
try {
package java.net existe la clase
URL, que representa una BufferedReader br = new BufferedReader(
direccin de Internet.
new InputStreamReader(
La clase URL tiene el mtodo
InputStream openStream(URL direccion.openStream()));
dir) que abre un stream con while((s = br.readLine()) != null)
origen en la direccin de Internet.
html += s + '\n';
A partir de ah, se trata como
cualquier elemento InputStream, br.close();
como se muestra en el ejemplo }
del cuadro.
catch(Exception e) {
System.err.println(e);
}

Programacin en Java 85
10. OTRAS CAPACIDADES DE JAVA
Java incorpora muchos conceptos de la informtica moderna. Desarrollarlos todos es difcil por motivos de
espacio, pero se puede hacer, al menos, mencin de las capacidades ms interesantes.
10.1. Java Foundation Classes (JFC) y Java 2D
Las JFC, Java Foundation Classes son un conjunto de componentes y caractersticas de ayuda en la
construccin de GUIs. Incluye todo tipo de elementos grficos como botones, paneles, mens y ventanas,
con ventajas sobre AWT. Swing es una parte de las JFC que permite incorporar en las aplicaciones
elementos grficos de forma ms verstil y con ms capacidades que AWT. Algunas caractersticas son:
1. Cualquier programa que usa componentes Swing puede elegir el aspecto de sus ventanas y elementos
grficos: entorno WS, entorno Motif (entornos Unix) o Metal (aspecto propio de Java)
2. Cualquier componente grfico de Swing presenta ms propiedades que el correspondiente elemento del
AWT: Los botones pueden incorporan imgenes, nuevos layouts y paneles, mens
3. Posibilidad de Drag & Drop; seleccionar componentes con el ratn y arrastrar a otro lugar de la pantalla
En la versin JDK 1.2 se incorpora como parte de las JFC Java 2D, que permite a los desarrolladores
incorporar texto, imgenes y grficos de calidad en 2D. Adems da soporte para imprimir documentos
complejos. A partir de la versin 1.2 de Java las JFC forman parte del propio JDK.
10.2. Java Media Framework (JMF) y Java 3D
El API JMF (Java Media FrameWork) especifica una arquitectura, un protocolo de transmisin de datos y
unos elementos grficos simples y unificados para la reproduccin de contenidos multimedia.
El API de Java 3D es un conjunto de clases para crear aplicaciones y applets con elementos 3D. Ofrece
la posibilidad de manipular geometras complejas en 3D. La ventaja frente a otros entornos de programacin
3D es que permite crear aplicaciones grficas 3D independientes del sistema. Java 3D es un conjunto de
clases, interfaces y bibliotecas de alto nivel que permiten aprovechar la aceleracin grfica hw que
incorporan muchas tarjetas, ya que las llamadas a los mtodos de Java 3D son transformadas en llamadas
a funciones de OpenGL o Direct3D. Conceptualmente y oficialmente Java 3D forma parte del API JMF, pero
las bibliotecas se instalan de forma independiente al JMF.
10.3. Javabeans
El API de JavaBeans hace posible escribir componentes sw en Java. Los componentes son elementos
reutilizables que poder incorporar grficamente a otros componentes como applets y aplicaciones usando
herramientas grficas de desarrollo. Cada componente ofrece sus caractersticas concretas (por ej. sus
mtodos pblicos y eventos) a los entornos grficos de desarrollo permitiendo su manipulacin visual. Son
anlogos a otros componentes de algunos entornos visuales, como por ejemplo los controles de VB. El BDK
(Beans Developer Kit) es un conjunto de herramientas para desarrollar JavaBeans. Se trata de un kit no
incorporado en los distintos JDK de Java.
10.4. Java en la red. Servlets, RMI y Java IDL
Java se presenta de forma estndar a todas las plataformas y SO, un conjunto de clases que permiten la
comunicacin entre aplicaciones que se ejecutan en distintas mquinas. El package java.net del API de
Java incluye las clases para establecer conexiones, crear servidores, enviar y recibir datos, y para el resto
de operaciones usadas en las comunicaciones en red. Existen otros APIs independientes preparados
especialmente para realizar tareas, como Servlets, RMI y Java IDL. Muchos de estos APIs usan
internamente las clases presentes en java.net.
Los Servlets son mdulos que permiten sustituir o usar Java en lugar de programas CGI escritos en otros
lenguajes como C/C++ o Perl. Los programas CGI son aplicaciones que se ejecutan en un servidor Web en
respuesta a una accin de un navegador remoto (peticin de pgina HTML, envo de los datos de un
formulario, etc.). Permiten generar pginas HTML dinmicas, en las que el contenido puede variar y que por
tanto no pueden almacenarse en un fichero en el servidor.
Los Servlets no tienen entorno grfico ya que se ejecutan en el servidor. Reciben datos y su salida son
principalmente ficheros de texto HTML. Los servlets son desarrollados usando el API Java Servlet, que es
una extensin de Java. Es necesario instalar el sw especfico de Java Servlet.
Tanto RMI (Remote Method Invocation) como Java IDL (Java Interface Definition Language) son
herramientas para desarrollar aplicaciones distribuidas. Estas aplicaciones presentan la caracterstica de
que una aplicacin puede ejecutar funciones y mtodos en varios ordenadores distintos. Usando una
referencia a un objeto que se encuentra en un equipo remoto, es posible ejecutar mtodos de ese objeto
desde una aplicacin de un equipo distinto.

Programacin en Java 86
RMI y Java IDL proporcionan los mecanismos con los que distintos objetos distribuidos se comunican y
transmiten informacin. Son por tanto tecnologas que permiten la creacin y uso de objetos distribuidos;
objetos o programas que interactan en diferentes plataformas y ordenadores a travs de una red.
RMI es una solucin basada ntegramente en Java. Incorpora mtodos para localizar los objetos remotos,
comunicarse con ellos e incluso enviar un objeto de Java, "por valor", de un objeto distribuido a otro. Java
IDL permite la conectividad entre objetos distribuidos utilizando CORBA.
CORBA (Common Object Request Broker Architecture) es un estndar para la interconexin entre objetos
distribuidos. Existen implementaciones de CORBA en varios lenguajes, lo que posibilita la comunicacin de
objetos en Java, C/C++, COBOL RMI y Java IDL estn incluidos en el JDK 1.2 de Sun. En el caso de
Java IDL se precisa de una utilidad adicional (idltojava) que genera el cdigo necesario para comunicarse
con cualquier implementacin CORBA.
10.5. Seguridad en Java
El entorno natural de trabajo es en red y en especial Internet. Entonces, la seguridad adquiere una
importancia vital. Desde su aparicin Java ha ido incorporando elementos para proporcionar un mayor
control sobre la seguridad de los datos y programas enviados a travs de una red. Los distintos JDK
incorporan herramientas para aadir seguridad a las aplicaciones Java: firmas digitales, transmisin segura
de datos... Java permite establecer distintos niveles de seguridad, lo que ofrece flexibilidad para asignar o
denegar permisos.
10.6. Acceso a bases de datos (JDBC)
JDBC (Java DataBase Connectivity) es el estndar de Java para conectarse con BBDD. Se estima que
aproximadamente la mitad del sw que se crea incorpora operaciones de R/W con BBDD. JDBC est
diseado para ser independiente de la plataforma y de la BBDD sobre la que se acte.
Para conseguir esta independencia, JDBC ofrece un sistema estndar de interconexin con las BBDD, muy
similar al SQL. Las BBDD comerciales crean los elementos necesarios que actan como puente entre JDBC
y su BBDD. La versin JDBC 1.0 forma parte del JDK 1.1. Despus de distintas revisiones la versin JDBC
2.0 se incluye en el JDK 1.2.
10.7. Java Native Interface (JNI)
JNI (Java Native Interface) es el interface de programacin de Java para ejecutar cdigo nativo, es decir
cdigo compilado propio de una plataforma o equipo. Se incluye en el JDK las herramientas necesarias para
su uso. JNI permite al cdigo Java que se ejecuta en la JVM interactuar con aplicaciones y bibliotecas
escritas en otros lenguajes, como C/C++ o incluso ensamblador. Incorpora a su vez las herramientas para
ejecutar cdigo Java desde aplicaciones desarrolladas en otros lenguajes.
El entorno JNI ofrece a los mtodos nativos usar objetos de Java de igual forma que el cdigo Java. Tanto
la parte de Java como la parte nativa de una aplicacin pueden crear, actualizar y acceder a los objetos
programados en Java y compartirlos.

Programacin en Java 87