You are on page 1of 38

2/7/2014 Curso Bsico de Java

http://geneura.ugr.es/~amorag/cursos/java/ 1/38
CURSO PROGRAMACIN DE
SERVIDORES WEB CON ACCESO
A BASES DE DATOS (2 Edicin)
Curso Bsico de Java
Este curso est dirigido principalmente a alumnos que no tengan conocimientos
sobre Java (o tengan muy pocos), de forma que pretende ser una primera
introduccin a las caractersticas y conceptos fundamentales de dicho lenguaje.
Debido a eso muchos de los conceptos simplemente se 'perfilarn' o se
nombraran sin entrar en demasiados detalles sobre los mismos.
Por otro lado, el curso tambin podr servir a usuarios con ms conocimientos en
el tema, puesto que dedica un captulo entero al tratamiento de Threads (Hebras),
que quiz sean una de las posibilidades ms potentes de Java, pero que
conllevan cierta dificultad en su programacin y en su entendimiento.
Introduccin
Historia de Java
Java surgi en 1991 cuando un grupo de ingenieros de Sun trataban de disear
un nuevo lenguaje de programacin destinado en principio a electrodomsticos
(sencillo y capaz de generar cdigo de tamao reducido). El continuo cambio en
las CPUs obligaba a actualizar los programas continuamente por lo que se pens
en desarrollar una herramienta que fuera independiente de la CPU. As pues,
idearon un lenguaje capaz de crear 'cdigo neutro' independiente del
electrodomstico, que posteriormente era ejecutado en una hipottica 'mquina
virtual', denominada Java Virtual Machine (JVM) que lo interpretaba y converta
a cdigo particular de cada CPU. Por esa razn se eligi como primer lema para
Java "Write Once, Run Everywhere" (escrbelo una vez, ejectalo en cualquier
lugar).
Tras tantos esfuerzos, ninguna empresa de electrodomsticos se interes por
Java, de modo que, a finales de 1995, comenz a introducirse como lenguaje de
programacin para computadores pasando a ser una herramienta necesaria,
puesto que Netscape Navigator 2.0 la introdujo como intrprete.
Desde ese momento Java ha evolucionado favorablemente, a principios de 1997
se public Java 1.1 y a finales de 1998 Java 1.2, con un crecimiento y mejora
prodigiosos, pasando de los 12 paquetes iniciales a 23 paquetes en la versin 1.1
y a 59 paquetes en la versin 1.2 (denominada Java 2). Esta evolucin ha
continuado y actualmente JDK (Java Development Kit) se encuentra en su
versin 1.5.0_06. En este curso se ver slo la punta del iceberg en que se ha
convertido.
La compaa Sun describe a Java como "simple, orientado a objetos, distribuido,
interpretado, robusto, seguro, de arquitectura neutra, portable, de altas
prestaciones, multitarea y dinmico". Lo bueno de esta definicin es que todo lo
que dice, que no es poco, es cierto, aunque en algunos aspectos mejorable.
NDICE
Introduccin
Historia
Programacin O.O.
Caracts. Generales
Pequeo Manual de
Programacin
Conceptos Iniciales
Palabras Reservadas
Estructuras Control
Clases y Objetos
Packages
Clases tiles
Compilar y Ejecutar
Primeros Ejemplos
Hola Mundo
Algo Ms Complicadillo
Uno con Errores
Ronda de Ejercicios
Hebras (Threads)
Cundo Usar Hebras
Cmo Crear Hebras
Inicializar una Hebra
Prioridades
Vida de una Hebra
Compartir Objetos
Ms Ejercicios

Contacto
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 2/38

Programacin Orientada a Objetos
Aunque el contenido de este curso se centra en Java, a continuacin se
describirn brevemente algunos conceptos que deberan tenerse claros antes de
trabajar con un lenguaje orientado a objetos como el que nos ocupa.
Se conoce como Clase a una estructura que contiene atributos y mtodos.
Dichos atributos sern variables correspondientes a caractersticas de la misma y
los mtodos sern funciones que realizarn operaciones relacionadas con la
clase (generalmente actuarn sobre los atributos de sta).
Un Objeto es una instancia concreta de una clase, cada uno ser diferente de los
dems, aunque sean instancias de la misma clase.
Se podra entender entonces que una clase equivaldra a un 'patrn' a partir del
que podemos crear objetos.
Se dice que una clase Encapsula datos, ya que desde fuera de la misma, por lo
general, no es posible trabajar con sus atributos si no es por medio de los
mtodos que ofrece.
Otro concepto fundamental es la Herencia, consistente en la posibilidad de
definir clases a partir de otras en el sentido de que tendrn muchos (o todos) los
atributos y mtodos comunes. Estas clases se conocen comunmente como padre
(la que se crea primero) e hija (la clase creada a partir de otra). Esta ltima a su
vez, podra aadir nuevos atributos o mtodos (que no tendra el padre) y ser
adems padre de otras clases.
Por ltimo, se conoce como Polimorfismo a la posibilidad que tiene un objeto de
'comportarse' de distintas formas usando el mismo mtodo. Es decir, el objeto
'decidir' qu mtodo usar (o cmo usarlo) en funcin de los parmetros que se
den en la llamada al mismo o en funcin de su clase.
Un programa orientado a objetos (POO) se basa en la creacin de una serie de
clases que 'encajan' perfectamente y que implementan la funcionalidad que se
pretente que tenga el programa. Dichas clases, debern trabajar con datos y
mtodos y comunicarse entre ellas para obtener los resultados deseados.
Para ampliar estos conceptos se puede acceder, por ejemplo, a POO en
Wikipedia.
Orientacin a Objetos en Java
El funcionamiento general de un POO se especifica en una clase principal la cual
contiene un mtodo fundamental que es el primero que se ejecuta, en Java es la
funcin main().
Al programar en Java no se parte de cero, ya que por defecto, en los paquetes de
desarrollo (JDK), hay un gran nmero de clases predefinidas, en las que se
'apoyan' las que nosotros creamos.
En Java, las clases son estructuras (definidas con class) que contienen una serie
de variables (atributos) y un conjunto de funciones (mtodos).
La encapsulacin viene representada en este lenguaje por los diferentes
permisos de acceso o visibilidad que podemos asignar tanto a las clases, como a
sus atributos y mtodos, pudiendo 'ocultarlos' al resto de las clases si lo
deseamos.
La herencia se usa muy a menudo en el desarrollo en Java, para ello se utiliza la
palabra clave extends entre dos clases (claseH extends claseP), dnde la
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 3/38
primera ser hija de la otra y heredar todos sus atributos y mtodos. Adems,
dicha clase hija (tambin llamada derivada) podr aadir nuevos atributos y
mtodos o redefinir los heredados. En Java una clase slo puede heredar de otra
(solo puede tener un padre), es lo que se denomina herencia simple.
El polimorfismo tambin est presente en Java, pudiendo encontrarse dos tipos
de polimorfismo. Por un lado existe la posibilidad de definir varias funciones con el
mismo nombre dentro de la misma clase (funciones sobrecargadas). La resolucin
de las mismas tiene que ver con la relacin que se establece entre la llamada a
un mtodo y el cdigo que efectivamente se asocia con dicha llamada. Esta
relacin se llama vinculacin o binding y puede ser temprana, en tiempo de
compilacin, o tarda, en tiempo de ejecucin. La vinculacin temprana es la ms
eficiente y es la que se da normalmente con funciones normales o sobrecargadas.
La vinculacin tarda es la que se utiliza con funciones redefinidas (tras heredar).
Por otro lado, es posible usar un objeto de la subclase como si fuera uno de la
superclase (usar los mtodos y variables propios de la superclase) y viceversa
(aunque con restricciones en el segundo caso).
Adems de clases, Java proporciona interfaces. Un interface es un conjunto de
declaraciones de mtodos sin contenido (sin cdigo). Si una clase implementa
(implements) un interface, debe definir todas las funciones especificadas en l
(crear el cdigo de las mismas). Una clase puede implementar ninguno, uno, o
varios interfaces. Un interface s soporta la herencia mltiple de varios interfaces.

Caractersticas Generales de Java
En esta seccin se describirn una serie de conceptos relacionados con la
programacin en Java, desde la forma habitual de desarrollar los programas, a las
normas (no establecidas) de programacin, pasando por ciertas particularidades
de este lenguaje.
Desarrollo en Java
Existen distintos programas comerciales que permiten desarrollar cdigo Java,
aunque lo ms comn es utilizar el Java Development Kit (JDK) (incluido en el
J2SE) que distribuye gratuitamente SUN. Se trata de un conjunto de programas y
libreras de clases (paquetes) que permiten desarrollar, compilar y ejecutar
programas en Java.
Adems, incorporan la posibilidad de ejecutar parcialmente el programa,
deteniendo la ejecucin en el punto deseado y estudiando en cada momento el
valor de cada una de las variables (con el denominado Debugger).
Del mismo modo, existe tambin una versin reducida del JDK, denominada JRE
(Java Runtime Environment) destinada nicamente a ejecutar cdigo Java(no
permite compilar).
Los IDEs (Integrated Development Environment) o entornos de desarrollo
integrados, son aplicaciones que permiten escribir el cdigo Java, compilarlo y
ejecutarlo de manera centralizada. Estos entornos permiten desarrollar las
aplicaciones de forma mucho ms rpida, incorporando en muchos casos libreras
con componentes ya implementados, los cuales se incorporan al proyecto o
programa de forma sencilla. Como inconvenientes se pueden sealar algunos
fallos de compatibilidad entre plataformas, y ficheros resultantes de mayor tamao
que los basados en clases estndar.
Existen varios IDEs comerciales como son Visual J++ (Microsoft) o JBuilder
(Borland). Un ejemplo de IDE de libre distribucin es Eclipse.
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 4/38
Aparte de lo mencionado, hay otras cuestiones a tener en cuenta a la hora de
desarrollar un programa en Java:
Los ficheros de cdigo deben tener la extensin '.java'. En ellos se pueden
definir una o varias clases, pero solo una ser la clase principal (la nica
clase pblica del fichero). Dichos ficheros deben tener el mismo nombre
que la clase principal que contienen (respetando maysculas y minsculas).
Los ficheros ya compilados tienen la extensin '.class' y existe siempre un
fichero de este tipo por clase.
Una aplicacin est compuesta por uno o varios ficheros '.class'
permitiendo as modularizar cada una de las partes de la misma en ficheros.
La ejecucin de una aplicacin comienza siempre por una clase que
contiene la funcin main() (sin aadir la extensin .class).
Las clases en Java se agrupan en packages, que se pueden definir como
libreras de clases. Si se declara una clase sin package se considerar
perteneciente a un package por defecto, default que ser el directorio
actual. Java proporciona un conjunto de paquetes al que se denomina API.
Particularidades de Java
La sintaxis es muy parecida a C++ y las palabras clave son las mismas a
excepcin de algunas que ya estn en desuso y aadiendo otras para
realizar tareas especficas de Java.
Todas las variables en Java son referencias y la utilizacin de la memoria
asociada a stas y a los objetos que se manejan es una funcin del
recolector de basura, llamado as porque es el encargado de liberar la
memoria de variables que ya no se van a utilizar en el programa
generalmente por cambio de mbito (cuando termina una funcin se libera
la memoria de las variables internas de la misma).
Todas las variables y funciones deben pertenecer a una clase, no hay
variables ni funciones globales.
Al contrario de C++, Java no utiliza destructores, sino que opcionalmente el
usuario puede incluir en las clases que cree un mtodo que se ejecutar
cuando el objeto vaya a ser reciclado, es el mtodo llamado finalize().
En Java todas las clases heredan, aunque no se especifique
explcitamente, de la clase general Object que hace de raz de toda la
jerarqua de clases. Los mtodos que define la clase object son de dos
tipos, mtodos que puede redefinir el programador, clone(), equals(),
toString(), finalize() y mtodos que no pueden ser redefinidos (llamados
mtodos final), como getClass(), notify(), notifyAll().
Java es un lenguaje fuertemente tipificado y la conversin entre referencias
de clases diferentes exige que ambas clases estn relacionadas mediante
herencia o mediante la implementacin de un interfaz en el caso de que la
referencia sea de un tipo interface.
'Normas' de Programacin
Este apartado no pretende ser una lista de normas estrictas, sino que describe un
conjunto de 'costumbres' que, cuando te conviertes en programador de Java, vas
adoptando poco a poco puesto que ayudan a entender mejor los programas y a
integrarte mejor en la gran comunidad de programadores que existe.
Es aconsejable usar nombres representativos para las variables, clases,
mtodos,.., en lugar de acrnimos, diminutivos, etc. De forma que solo con
el nombre podamos hacernos una idea de lo que representa cada
elemento.
En Java es habitual utilizar nombres completos en minsculas para
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 5/38
variables excepto en las situaciones:
El nombre consta de varias palabras y normalmente se pone una
detrs de otra con la primera letra de cada palabra en maysculas:
Ej. menorNumero.
Los nombres de clases e interfaces comienzan siempre por
mayscula: Ej. Circulo.
Los nombres de las variables finales o constantes, se definen
siempre con maysculas: Ej. ALPHA.
Los nombres de objetos y mtodos comienzan siempre por minscula.
Es una buena costumbre agrupar nuestras clases en paquetes (packages)
para saber cules estn relacionadas entre si y poder reutilizarlas.
El nombre de los paquetes de clases suele estar en minsculas y puede
constar de varios nombres unidos por puntos. Todas las clases que estn
en el mismo paquete deben estar en el mismo directorio. Los nombres
compuestos de los paquetes estn relacionados con la jerarqua de
directorios en que se guardan las clases.
Es recomendable comentar bien el cdigo, casi llegando a abusar, pues
incluso nosotros mismos lo agradeceremos al releer nuestros propios
programas un tiempo despus.
Se suelen usar tabulaciones y lneas en blanco para situar el cdigo
anidado de forma ms visual.


Pequeo Manual de Programacin en Java
Este captulo ofrece una guia de referencia inicial de los tipos posibles, palabras
reservadas, operadores y estructuras de control que podemos usar para
programar en Java. Adems comenta la forma de definir de clases, variables,
mtodos, packages e interfaces, revisando algunas de las posibilidades que nos
ofrece este lenguaje, as como sus peculiaridades o restricciones.
Conceptos iniciales
En Java se tienen como tipos primitivos: char, byte, short, int, long, float,
double, boolean.
Hay que tener cuidado con el tipo boolean que toma como valores true o false los
cuales no son equivalentes a 1 y 0 (como en C++).
Para definir e inicializar una variable, basta con seguir el esquema:
TipoClase nombreVariable; //definicin
nombreVariable = valor | new Clase(); //inicializacin
Los nombres de las variables debern contener solo caracteres alfanumricos o
'_' y no ser iguales a ninguna palabra reservada.
Una variable podr ser un tipo primitivo o un tipo referencia (array u objeto). En
los dos ltimos casos deber inicializarse usando la instruccin new.
Una cadena en Java es un objeto del tipo String, pero an as puede ser tratado
como un tipo primitivo. Por ejemplo, para inicializar una cadena no es necesario
hacer un new, sino que se pueden crear como una variable normal:
Ej. String micadena = "cadena de prueba"; // creada como tipo
primitivo
Aunque si se desea, se puede inicializar con new:
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 6/38
Ej. String micadena = new String("cadena de prueba"); // creada
como objeto
Los arrays igualmente son objetos y se deben crear segn la estructura:
TipoClase [ ]..[ ] nombreArray; //definicin
nombreArray = new TipoClase[num_elems1][num_elems2]...[num_elemsN];
//inicializacin
Teniendo en cuenta que si se trata de un array de objetos de una clase,
deberemos recorrerlos inicializando cada uno de ellos usando el constructor de su
clase (haciendo un new para cada uno).
Al igual que en C/C++, los arrays tienen ndices entre 0 y (nmero de elementos-
1).
El valor nulo en Java es null y se utiliza para liberar la memoria de las variables
asignndoselo como si fuera un valor.
En Java, las conversiones entre tipos se hacen de forma automtica si pasamos
de un tipo a otro de ms precisin (de int a long, de float a double). Entre clases
ocurre igual si queremos convertir un objeto de una subclase (hijo) en otro de su
superclase (padre), ya que la subclase tendr todos los mtodos y variables de la
superclase (gracias la herencia).
En los dems casos es posible 'forzar' conversiones entre tipos y clases (siempre
dentro de unos mrgenes), es lo que se conoce como casting. La forma de
convertir un tipo o clase en otro sera:
TipoClase1 variable1
TipoClase2 variable2
variable1 = (TipoClase1) variable2; // en lugar de variable2 podramos tener
una expresin
Como se ha dicho se deben respetar ciertas normas, como que algunos tipos no
se pueden convertir mediante casting en otros (Ej. un boolean no puede
convertirse en int) o que, en el caso de las clases, para convertir un objeto de una
clase A en uno de una clase B, ambas deben estar relacionadas mediante
herencia. Si A es superclase de B, deberemos hacer un casting explcito como se
indica arriba y podra dar errores ya que la clase A podra no tener ciertos
mtodos o variables de la clase B.
En cualquier caso, tambin existen mtodos para realizar conversiones entre tipos
poco compatibles en principio (como pueden ser cadenas y nmeros)
Operadores
Los operadores aritmticos son + , - , * , / y % (resto de la divisin).
Los operadores relacionales son > , < , >= , <= , == (igual) y != (distinto).
Los operadores lgicos son && (and) , || (or) , ! (negacin).
Otros operadores: ++ (incremento) , -- (decremento) , = (asignacin).
El operador + tambin se usa para la concatenacin de cadenas.
El operador instanceof devuelve un valor booleano y se usa para saber si una
variable es de una determinada clase.
Ej. mivar instanceof UnaClase //devuelve true si miVar es de la
clase UnaClase .
Consideraciones
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 7/38
Para finalizar cada sentencia se debe poner un ' ; '.
Los Comentarios en Java se marcan con ' // ' al principio de cada lnea a comentar
o con ' /* ' y ' */ ' delimitando un conjunto de lneas de comentario.
Para determinar un bloque de cdigo se usan como delimitadores ' { ' como inicio
y ' } ' como fin del bloque.
Java es sensible a maysculas y minsculas, es decir, dos nombres sern iguales
solo si coinciden todas sus letras y estn en maysculas/minsculas las mismas
letras: Ej. 'Tierra' es diferente de 'tierra' y ambas son diferentes de 'TIERRA'.

Palabras Reservadas
A continuacin se muestra una lista con las palabras reservadas de Java, sin
ningn tipo de explicacin, sino nicamente para tener constancia de su
existencia. Si se desea ms informacin, se recomienda consultar la
documentacin existente al respecto.
abstract
boolean
break
byte
case
catch
char
class
continue
default
do
double
else
extends
final
finally
float
for
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

Estructuras de Control
En este apartado se comentarn brevemente las estructuras de control (para
determinar el flujo del programa) que se pueden usar en Java.
Condicionales:
if
(ExpresionBooleana)
{
sentencias;
}
if
(ExpresionBooleana)
{
sentencias1;
} else {
sentencias2;
}
if
(ExpresionBooleana1)
{
sentencias1;
} else if
(ExpresionBooleana2)
{
sentencias2;
} else if
(ExpresionBooleana3)
{
sentencias3;
...
} else {
sentenciasN;
}
switch
(Expresion) {
case
valor1:
sentencias1;
break;
case
valor2:
sentencias2;
break;
case
valor3:
sentencias3;
break;
...
[default:
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 8/38
sentenciasN;]
}
Bucles:
while
(ExpresionBooleana)
{
sentencias;
}
for (Inicializacion;
ExpresionBooleana; Incremento) {
sentencias;
}
do {
sentencias;
} while
(ExpresionBooleana);

Como nota indicar que en el bucle for, la inicializacin solo se hace la primera vez
y el incremento una vez terminadas las sentencias. Adems sealar que es
posible hacer varias inicializaciones y/o varios incrementos, en ambos casos
separando por comas las diferentes expresiones.
Excepciones:
La excepciones son errores 'controlados' y 'recuperables' que surgen durante la
ejecucin de un programa. En Java se pueden 'capturar' y actuar en
consecuencia, para ello se usa la estructura try...catch, en la cual el cdigo en el
bloque try es supervisado, de forma que si ocurre una excepcin, se pasar a
hacer las acciones definidas en el bloque catch correspondiente a dicho error
(habr uno por cada error a controlar). Existe tambin un bloque finally que se
ejecuta ante cualquier tipo de error (no controlado anteriormente en un catch).
try {
sentenciasT;
} catch (ClaseExcepcion1 nombreVariableExcepcion1) {
sentenciasE1;
} catch (ClaseExcepcion2 nombreVariableExcepcion2) {
sentenciasE2;
} ...
finally {
sentenciasF;
}
Para interrumpir el flujo normal del programa y modificarlo brscamente, se usan
las instrucciones:
break, sale del bloque, ya sea una condicin o un bucle, sin ejecutar ninguna
sentencia ms.
continue, til solo en bucles, en los que pasa a la siguiente iteracin del mismo.
return, sale de un mtodo de manera inmediata. Suele usarse junto con un valor
que es el que devuelve el mtodo.

Clases y Objetos
En este apartado se describir con brevedad la forma comn de definir una clase,
los atributos y mtodos, as como las diferentes opciones con las que se pueden
crear y la instanciacin de un objeto de dicha clase.
En general, la forma usual de definir una clase es:
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 9/38
[visibilidad] [modificador] class NombreClase [herencia] [implementacin] {
// definicin de variables y mtodos
...
}
Dnde:
La visibilidad es el mbito en el que es conocida una clase, es decir, determina
desde qu paquetes o clases es posible crear objetos de dicha clase y trabajar
con ellos.
Con public la clase podr ser vista desde cualquier otro paquete (o clase).
Mientras que con package la clase solo podr ser vista dentro el mismo paquete.
Es la opcin por defecto si no se especifica nada.
Se puede usar el modificador abstract para definir un tipo de clases de las que
no se pueden crear objetos. Su utilidad es que otras clases deriven o hereden
(extends) de ella, proporcionndoles un marco o modelo a seguir y una serie de
mtodos de utilidad general.
Es posible tener mtodos completamente definidos dentro de una clase abstract y
adems tener mtodos abstract.
La herencia, como ya se coment anteriormente, es simple (solo entre una clase
hija y otra padre) y se identifica usando la palabra reservada extends ms la
clase de la que se hereda (clase padre). Ej. class Circulo extends Figura.
Debemos recordar que mediante la herencia conseguimos que la clase hijo
disponga de las mismas variables y funciones que la clase padre, las cuales
puede redefinir. Adems, dicha clase podr tener otras variables y mtodos
propios.
La implementacin se refiere a las posibilidades que ofrecen los interfaces, ya
comentados en un apartado anterior. Para definir una clase que implemente un
interfaz ya definido se usa la palabra reservada implements, junto con el nombre
del interfaz (o interfaces separados por comas) a implementar. Ej. class
Cuadrado implements InterfazFigura. Recordamos nuevamente que un
interfaz es un conjunto de declaraciones de funciones (funciones vacas, se
podra decir) agrupadas bajo un nombre al igual que una clase.
La definicin de un interfaz sera:
[visibilidad] interface NombreInterfaz [herencia] [implementacin] {
// definicin de funciones
...
}
Al igual que una clase, un interfaz podr heredar (extends) de otro u otros (cosa
que no pueden hacer las clases), sin ms que separarlos por comas. Del mismo
modo, tambin podr implementar (implements) a otro u otros.
Los interfaces se suelen definir en ficheros con su nombre y solo podrn ser
public o package (al igual que las clases).
Atributos (variables miembro)
Para declarar un atributo de una clase, basta con declararlo como cualquier
variable dentro del cuerpo de dicha clase, la forma sera:
[visibilidad] TipoClase nombreAtributo;
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 10/38
dnde la visibilidad ser public,package,private o protected, siendo public y
package similares a los comentados para la definicin de clases y private y
protected sirven para asegurar que los atributos solo se puedan acceder desde
dentro de la misma clase (desde los mtodos de sta).
Existe un tipo de variables llamadas variables de clase que se definen
anteponiendo la palabra reservada static y que tienen como particularidad que
son variables comunes a todos los objetos, pero que solo tienen sentido y solo se
manejan a nivel de clase. Ej. un contador de objetos creados de una clase.
Suelen usarse para definir constantes que puedan usar todos los objetos de la
clase.
Por ltimo hablaremos de las variables declaradas con la palabra clave final, que
son aquellas que no pueden cambiar su valor a lo largo de la ejecucin (equivalen
a constantes).
Mtodos (funciones)
Los mtodos son funciones definidas dentro de una clase, la forma general de
declararlos es:
[visibilidad] [modificador] ClaseTipo_ValorRetorno nombreMtodo (
[ClaseTipo_parametro1 nombreParametro1, ..., ClaseTipo_parametroN
nombreParametroN] ) {
sentencias;
}
dnde la visibilidad ser nuevamente public,package,private o protected, con
el mismo significado que en el caso de los atributos.
Los parmetros del mtodo se pasan siempre por valor, es decir, aunque se
modifiquen dentro del mismo, su valor no cambiar fuera de l. Cuando se pasan
referencias, ya sean arrays u objetos, la referencia tampoco podr cambiar, pero
sus valores (los elementos del array o los atributos del objeto) si que podrn
hacerlo.
Como se puede ver los parmetros de los mtodos son optativos, de modo que si
no tienen, basta con dejar los parntesis vacos.
Los mtodos tambin se pueden declarar con el modificador abstract, al igual
que las clases. Su utilidad es definir un modelo de mtodo para las clases que
hereden de aquella en la que estn definidos. Si una clase tiene un mtodo
abstract, entonces la clase deber ser abstract.
Los mtodos tienen visibilidad directa de las variables miembro de la clase en la
que estn definidos, es decir, pueden hacer referencia a ellas.
Dentro de los mtodos se pueden declarar variables locales que tendrn como
mbito dicho mtodo (al finalizar las eliminar el recolector de basura).
Para hacer referencia a algn elemento de la clase misma en la que se encuentra
el mtodo se utiliza la palabra this. Del mismo modo, para hacer referencia a una
variable o mtodo de la clase padre de en la que est el mtodo (en caso de que
la haya), se utiliza la palabra super.
El valor de retorno es nico y se devolver usando la instruccin return dentro
del cuerpo del mtodo, finalizando el mismo de manera inmediata.
Al igual que las variables, tambin existen mtodos de clase, que se declaran
igualmente anteponiendo static y que nuevamente solo tienen sentido a nivel de
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 11/38
clase. Ej. funcin que incrementa el nmero de objetos creados de una clase.
Existe un tipo de mtodos que deben definirse para todas las clases (para evitar
errores), son los llamados constructores y son funciones que tienen como
objetivo inicializar los atributos de un objeto a la hora de crearlo. Deben tener el
mismo nombre que la clase en la que se definen y no tienen valor de retorno.
Puede haber varios, aunque con distinto nmero de parmetros. Los
constructores son llamados cuando inicializamos un objeto con la instruccin new.
Los constructores pueden ser llamados (con el mismo nombre de la clase y los
parmetros pertinentes) desde dentro de otros constructores o mtodos de clase
(incluso de clases hijas usando super), pero no pueden ser llamados desde otro
tipo de mtodos.
Si no se define ninguno, Java crea uno automticamente en el que inicializa las
variables con sus valores por defecto.
Es posible definir varios mtodos con el mismo nombre dentro de la misma clase,
aunque con distinto nmero y/o tipo de parmetros, es lo que se conoce como
sobrecarga de un mtodo y con ella se implementa el anteriormente citado
polimorfismo en Java.
Del mismo modo, es posible sobreescribir los mtodos heredados en la clase hija,
es la llamada redefinicin.
Objetos
Los objetos son instancias de las clases, como ya se coment, cada objeto es
diferente de los dems, aunque sean de la misma clase, por lo que tendr valores
propios para sus atributos que determinarn un estado diferente de los dems.
Para crear un objeto basta con declararlo como de una clase y despus
inicializarlo (llamando al constructor), por ejemplo:
MiClase miObjeto;
miObjeto = new MiClase();
Para acceder a los atributos y los mtodos que tiene el objeto (los que ofrece la
clase y siempre que lo permita la visibilidad), bastar con usar el operador ' . ', por
ejemplo:
miObjeto.x = 10;
miObjeto.calcularY(20);

Packages
Para concluir el captulo, en esta seccin hablaremos brevemente de los
packages, su gestin y su utilidad en Java.
Un package es un conjunto de clases relacionadas de alguna forma (es similar a
una librera en otros lenguajes). Todas las clases del mismo package debern
estar en el mismo directorio, de forma que se establece una relacin directa entre
package y directorio.
Un usuario podr crear sus propios packages escribiendo al principio del fichero
con la clase a incluir la instruccin:
package nombrePackage;
Generalmente, estos nombres estarn en minscula y contendrn varias palabras
separadas por puntos, que se corresponden usualmente con la estructura de
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 12/38
directorios en la que se encuentra el package, a partir del path que determina la
variable CLASSPATH (de la que se hablar ms adelante).
Para utilizar las clases incluidas en un package (las pblicas), se usa la
instruccin:
import nombrePackage.[*|NombreClase.class];
Pudiendo elegir una clase concreta o todas las clases del package con ' * '.
Esto se debe hacer explcitamente para todos los que queramos importar, aunque
sean sub-packages de otros, ya que esto ltimo no se hace de manera
automtica.

Clases tiles
Este captulo enumera y describe en pocas lneas una serie de clases que seguro
resultarn de utilidad al alumno. Algunas de ellas se comentarn con ms
profundidad en captulos posteriores.
Wrappers
Son clases diseadas para complementar los tipos primitivos (ya
que no son objetos), aadiendo al valor en si (definido como una
variable miembro de la clase) una serie de mtodos para facilitar
su uso. Los wrappers definidos son Byte, Short, Integer, Long,
Float y Double
java.lang.Math
Proporciona mtodos para realizar operaciones matemticas, as
como algunas constantes como PI o E.
Ej. Math.random()
Colecciones
Una coleccin no es ms que un conjunto de objetos que se
agrupan, cualquier coleccin se identifica por el interfaz
Collection.
Son colecciones las clases java.util.Vector, java.util.HashSet, ... y
tambin son colecciones los interfaces java.util.List, java.util.Map,
...
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 13/38
- Collection: define mtodos para tratar una coleccin genrica
de elementos.
- Set: Coleccin de elementos que no admite repeticin.
- SortedSet: es un Set ordenado segn un criterio establecido.
- List: admite elementos repetidos y mantiene el orden de
insercin.
- Map: Conjunto de pares, clave/valor, sin repeticin de claves.
- SortedMap: es un Map ordenado segn un criterio establecido.
- Iterator: Interfaz de soporte utilizado para recorrer una
coleccin y para borrar elementos.
- ListIterator: interfaz de soporte que permite recorrer List en
ambos sentidos.
- Comparable: interfaz de soporte que declara el mtodo
compareTo() que permite ordenar las diferentes colecciones
segn un orden natural.
- Comparator: interfaz de soporte que declara el mtodo
compare() y se utiliza en lugar de Comparable: cuando se desea
ordenar objetos no estndar o sustituir a dicha interface.
java.awt
AWT son las siglas de Abstract Windows Toolkit y es la parte de
Java que se permite construir interfaces grficas. Para construir
una interfaz, se necesitan al menos tres elementos, un
contenedor, unos componentes y un modelo de eventos.
El contenedor es la ventana o parte de la ventana donde se
sitan los componentes.
Los componentes son mens, botones, barras de
desplazamiento, cajas y reas de texto, etc.
El modelo de eventos es la herramienta que nos permite
controlar las acciones del usuario sobre los componentes, de
modo que cada vez que el usuario realiza una accin se produce
un evento y AWT crea un objeto de la clase de evento
correspondiente derivada de AWTEvent. El evento ser
posteriormente gestionado por un objeto que debe conocer el
componente que lo ha recibido.
De forma que se diferencian dos tipos bsicos de objetos, los
que reciben los eventos (event source) y los que manejan los
eventos (event listener).
Los objetos event source deben 'registrar' los objetos que
habrn de gestionar sus eventos, mientras que los objetos event
listener deben implementar los mtodos adecuados para
manejar un cada evento. La forma ms sencilla de hacerlo es
implementar el interfaz Listener de forma adecuada.
Threads
Los threads (hebras) o hilos de ejecucin permiten organizar los
recursos del ordenador de forma que pueda haber varios
programas o varias partes del mismo programa ejecutndose en
paralelo. Un hilo de ejecucin realizar las acciones indicadas en
el mtodo run().
(esta clase se estudiar con ms detalle en captulos posteriores
del curso)
Exceptions
Las excepciones y su tratamiento (forma de capturarlas,
respuesta a las mismas), ya se comentaron en el captulo
anterior, por lo que no se entrar en grandes detalles. Solo cabe
mencionar que una excepcin no es igual que un error, ya que
que las excepciones son recuperables, mientras que los errores
no lo son, de hecho las excepciones estn organizadas en una
jerarqua que parte de la clase java.lang.Exception mientras que
los errores tipificados estn organizados a partir de la clase
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 14/38
java.lang.Error.
Tambin hay que comentar la posibilidad que tiene el
programador de lanzar excepciones (throw) cuando l lo desee
(al detectar un dato en formato incorrecto para el programa, por
ejemplo). sto se hara mediante objetos de dicha clase
Exception
Para ampliar los conceptos acerca de cualquiera de estas clases, as como de
otras muchas que pudieran resultar de utilidad para el programador, se
recomienda revisar la documentacin que ofrece SUN via internet, por ejemplo:
Documentacin sobre todas las distribuciones de Java
Documentacin sobre API de JDK

Compilar y Ejecutar
Antes de nada cabra definir muy brevemente lo que se entiende por compilar y
ejecutar.
Compilar un programa consiste en convertir dicho programa, que no ser ms
que cdigo (texto) escrito en un lenguaje de programacin y guardado en uno o
varios ficheros, en cdigo mquina que pueda interpretar la CPU. En el caso de
Java, se convierte en realidad en el llamado bytecode (fichero '.class') que es el
cdigo que deber interpretar la mquina virtual de Java (JVM) que tengamos
instalada en nuestro sistema operativo. Debemos recordar que una de las
caractersticas que hacen potente a Java es la posibilidad de ejecutar el mismo
bytecode en diferentes CPUS y sistemas operativos.
Durante la compilacin se identifican algunos posibles errores que pueda haber
en el programa, como errores sintcticos (algo mal escrito segn la sintaxis del
lenguaje de programacin), variables o mtodos no declarados, fallos en la
llamada a mtodos, etc. Para que compile correctamente un programa no deber
haber ningn error.
Ejecutar un programa consiste en interpretar el cdigo mquina generado en la
compilacin, dando como resultado la aplicacin que hayamos programado. Java
nuevamente se desmarca del resto (que genera ficheros ejecutables ('.exe' en
windows)), puesto que tiene un comando para ejecutar el programa que lanza la
mquina virtual que interpreta el bytecode.
Durante la ejecucin tambin pueden surgir errores, los cuales no pueden ser
detectados en tiempo de compilacin, pues generalmente se trata de referencias
en memoria no controladas (intentos de acceso fuera de los lmites de un array,
por ejemplo) o valores incorrectos, y estos accesos o asignaciones solo se
producen durante la ejecucin.
Centrndonos ya en nuestro tema, el primer paso sera instalar los paquetes
necesarios para compilar un programa en Java (Java Development Kit (JDK)),
posteriormente deberemos comprobar que la variable del sistema PATH contiene
la rutas de los programas de Java y la variable CLASSPATH tiene las rutas de los
paquetes del API de la JDK (las distribuciones para Windows suelen actualizar
dichas variables de manera automtica).
Compilacin de un Programa
El comando para compilar desde la lnea de comandos de cualquier sistema
operativo (ventana de MS-DOS o command en Windows y terminal en Linux) es:
javac [opciones] fichero.java
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 15/38
Las opciones se pueden ver si se ejecuta sin argumentos. De todas ellas, la ms
utilizada y a su vez la que ms complicaciones crea a los nuevos programadores o
usuarios es la opcin -classpath. Esta opcin se utiliza para incluir los directorios
donde se deben buscar las clases necesarias para compilar el programa
deseado. Las rutas de dichos directorios se deben escribir separadas por ' ; ' en
Windows o por ' , ' en Linux. Cualquier clase necesaria que no est incluida en
esta lista provocar un error del compilador.
En el caso ms sencillo, supongamos que queremos compilar un fichero file.java
que pertenece al paquete mipaquete, y el directorio actual es c:\mipaquete la
sentencia para compilar este fichero sera:
javac -classpath . file.java
Pero supongamos que el fichero file.java contiene una sentencia import
otropaquete.mio.MiClase y el fichero de esta clase, MiClase.java, est en el
directorio c:\otropaquete\mio\MiClase. En este caso la sentencia anterior dara un
error por que no puede encontrar la clase MiClase y la sentencia correcta sera:
javac -classpath .;..\otropaquete\mio file.java
Otra posible situacin sera que la clase que hemos includo no est en nuestro
directorio sino que se trate de una clase includa en un fichero '.jar'. Para estos
casos el classpath debe incluir la direccin y nombre completo del fichero y debe
ponerse el primero. Por ejemplo:
javac -classpath
direccion.ficherojar.jar;.;..\otropaquete\mio file.java
Ejecucin de un Programa
Es importante sealar que para que un programa en Java 'haga algo', es
necesario definir dentro de una clase pblica (clase principal) un mtodo main.
En el comenzar todo el proceso del programa y generalmente tendr la forma:
public static void main (String[] args) {
sentencias_programa_principal;
}
Para ejecutar un programa Java el comando que se debe utilizar es:
java [opciones] programa
El programa debe ser el nombre de un fichero '.class' (sin poner la extensin) que
incluya la funcin main.
Las opciones disponibles se pueden ver si se ejecuta el comando sin argumentos
al igual que al compilar.
De nuevo, la opcin ms engorrosa es -classpath, que sigue las mismas reglas
que para el comando anterior.
Como ejemplo podemos ver las sentencias para ejecutar los programas
compilados en los ejemplos anteriores:
java -classpath . file
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 16/38
java -classpath .;..\otropaquete\mio file
java -classpath
direccion.ficherojar.jar;.;..\otropaquete\mio file


Primeros Ejemplos
En este captulo, se mostrar el cdigo de varios ejemplos sencillos (clsicos en el
aprendizaje de cualquier lenguaje de programacin), comentados para su mejor
comprensin, y se pedir al alumno que los pruebe, arregle el que tiene errores y
que intente comprenderlos.
Hola Mundo Java!
//fichero: HelloJava0.java
public class HelloJava0 {
// funcin principal del programa
public static void main(String[] args) {
HelloJava0 helloJava = new HelloJava0(); //creamos un
objeto de la clase
helloJava.printHello(); //usamos el mtodo printHello
de la clase
}
// mtodo miembro de la clase
public void printHello(){
System.err.println("Hola, Java!");
}
}
Compila y ejecuta el ejemplo anterior (copindolo a un fichero) para ver cmo
funciona.


Algo Ms Complicadillo
//fichero: HelloJava1.java
public class HelloJava1 extends javax.swing.JComponent
{
// se trata de una clase que es un JComponent.
public static void main(String[] args) {
javax.swing.JFrame f = new
javax.swing.JFrame("HelloJava1");
f.setSize(300, 300);
// aade un componente al contenedor.
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 17/38
f.getContentPane().add(new HelloJava1( ));
f.setVisible(true);
}
public void paintComponent(java.awt.Graphics g) {
// repinta el objeto cada vez que es necesario
g.drawString("Hola, Java!", 125, 95);
}
}
//fichero: HelloJava2.java
// import ms complejo
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloJava2 extends JComponent implements
MouseMotionListener {
// es una clase componente que va a responder a los
eventos relacionados con el movimiento del ratn
// Coordenadas del mensaje
int messageX = 125, messageY = 95;
String theMessage;
public HelloJava2(String message) {
//constructor
theMessage = message;
// establece que el objeto que va a manejar los
eventos del ratn va a ser l mismo.
addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
g.drawString(theMessage, messageX, messageY);
}
public void mouseDragged(MouseEvent e) {
//para el evento drag and drop se invoca este
mtodo.
// Guarda las coordenadas del ratn y muestra el
mensaje.
messageX = e.getX( );
messageY = e.getY( );
repaint( );
}
public void mouseMoved(MouseEvent e) {}
// no se necesita as que no se implementa
public static void main(String[] args) {
JFrame f = new JFrame("HelloJava2");
// Hace que la aplicacin termine cuando se cierre
la ventana.
// WindowAdapter se utiliza para crear listeners
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 18/38
para los eventos de la ventana, y se redefine en lnea
el mtodo windowClosing
f.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent we) {
System.exit(0); }
});
f.setSize(300, 300);
f.getContentPane( ).add(new HelloJava2("Hola,
Java!"));
f.setVisible(true);
}
}
//fichero: HelloJava3.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HelloJava3 extends JComponent
implements MouseMotionListener, ActionListener {
// Coordenadas del mensaje
int messageX = 125, messageY = 95;
String theMessage;
//nuevo componente, un botn
JButton theButton;
// ndice del Color actual seleccionado del array
int colorIndex;
// array de colores, es static, porque se trata de
una variable de clase.
static Color[] someColors = { Color.black, Color.red,
Color.green, Color.blue, Color.magenta };
// Constructor, crea el boton, lo aade al panel y
establece quien maneja las acciones del botn, this.
public HelloJava3(String message) {
theMessage = message;
theButton = new JButton("Cambiar Color");
setLayout(new FlowLayout( ));
add(theButton);
theButton.addActionListener(this);
addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
g.drawString(theMessage, messageX, messageY);
}
public void mouseDragged(MouseEvent e) {
// Guarda las coordenadas del ratn y muestra el
mensaje.
messageX = e.getX( );
messageY = e.getY( );
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 19/38
repaint( );
}
public void mouseMoved(MouseEvent e) {}
// este mtodo es del interfaz ActionListener y se
llamar cada vez que se ejecute un evento del tipo
ActionEvent
public void actionPerformed(ActionEvent e) {
// comprobamos que se ha pulsado el botn
if (e.getSource( ) == theButton)
changeColor( );
}
// este mtodo cambiar el ndice del color y
asignar el nuevo color como color para la fuente del
componente
// Esta sincronizado con el mtodo currentColor
porque nunca deben realizarse a la vez, para evitar
errores con la variable colorIndex
synchronized private void changeColor( ) {
// Se pasa al siguiente color (se cambia el ndice).
if (++colorIndex == someColors.length)
colorIndex = 0;
setForeground(currentColor( )); // Se usa el nuevo
color.
repaint( ); // Se dibuja de nuevo para que podamos
ver el cambio de color.
}
synchronized private Color currentColor( ) {
return someColors[colorIndex];
}
public static void main(String[] args) {
JFrame f = new JFrame("HelloJava3");
// Hace que la aplicacin termine cuando se cierre
la ventana.
f.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent we) {
System.exit(0); }
});
f.setSize(300, 300);
f.getContentPane( ).add(new HelloJava3("Hola,
Java!"));
f.setVisible(true);
}
}
//fichero: HelloJava4.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// esta clase es una hebra, es la segunda forma de
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 20/38
crear hebras, con Runnable
public class HelloJava4 extends JComponent
implements MouseMotionListener, ActionListener,
Runnable {
// Coordenadas del mensaje
int messageX = 125, messageY = 95;
String theMessage;
JButton theButton;
int colorIndex; // ndice del Color actual
seleccionado del array.
static Color[] someColors = { Color.black, Color.red,
Color.green, Color.blue, Color.magenta };
// variable booleana para decir si parpadea o no.
boolean blinkState;
// el constructor crea adems de todo lo anterior una
hebra y la inicializa.
// esta hebra se va a encargar de mostrar y ocultar
el mensaje con una ejecucin
// separada a la ejecucin secuencial de nuestro
pequeo programa.
public HelloJava4(String message) {
theMessage = message;
theButton = new JButton("Cambiar Color");
setLayout(new FlowLayout( ));
add(theButton);
theButton.addActionListener(this);
addMouseMotionListener(this);
Thread t = new Thread(this);
t.start( );
}
// segn el valor de la variable blinkState, cambia el
color a uno nuevo o al mismo color del fondo.
public void paintComponent(Graphics g) {
g.setColor(blinkState ? getBackground() :
currentColor( ));
g.drawString(theMessage, messageX, messageY);
}
public void mouseDragged(MouseEvent e) {
messageX = e.getX( );
messageY = e.getY( );
repaint( );
}
public void mouseMoved(MouseEvent e) {}
public void actionPerformed(ActionEvent e) {
// comprobamos que se ha pulsado el botn
if (e.getSource( ) == theButton)
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 21/38
changeColor( );
}
synchronized private void changeColor( ) {
// Se pasa al siguiente color (se cambia el ndice).
if (++colorIndex == someColors.length)
colorIndex = 0;
setForeground(currentColor( )); // Se usa el nuevo
color.
repaint( ); // Se dibuja de nuevo para que podamos
ver el cambio de color.
}
synchronized private Color currentColor( ) {
return someColors[colorIndex];
}
// este mtodo es el que ejecuta la hebra
independiente e ir repintando cada medio segundo el
mensaje
public void run( ) {
try {
while(true) {
blinkState = !blinkState; // Toggle blinkState.
repaint( ); // Show the change.
Thread.sleep(500);
}
}
catch (InterruptedException ie) {}
}
public static void main(String[] args) {
JFrame f = new JFrame("HelloJava4");
// Hace que la aplicacin termine cuando se cierre
la ventana.
f.addWindowListener(new WindowAdapter( ) {
public void windowClosing(WindowEvent we) {
System.exit(0); }
});
f.setSize(300, 300);
f.getContentPane( ).add(new HelloJava4("Hola,
Java!"));
f.setVisible(true);
}
}
Copia las clases anteriores a ficheros y compila y ejecuta para observar cual es
su salida.
(cuidado con los comentarios que ocupan ms de una lnea, ya que al
copiarlos pueden quedar lneas de comentario sin su correspondiente '//' y
producir errores de compilacin)


2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 22/38
Uno con Errores
A continuacin se muestra un ejemplo sencillo que contiene varios errores fciles
de identificar para que el alumno se vaya familiarizando con ellos (aunque seguro
que cuando comience a programar acabar odindolos, cosa normal).
//fichero: EjemploErrores.java
class EjemploErrores {
public static void main(String arg[]) {
System.out.println("Comienza main()...);
Circulo c = new Circulo(2.0, 2.0, 4.0);
System.out.prntln("Radio = " + c.r + " unidades.");
System.out.println("Centro = (" + c.x + "," + c.y +
") unidades.");
Circulo c1 = new Circulo(1.0, 1.0, 2.0);
Circulo c2 = Circulo(0.0, 0.0, 3.0);
c = c1.elMayor(c2);
System.out.println("El mayor radio es " + c.r +
".");
c = new Circulo(); // c.r = 0.0;
c = Circulo.elMayor(c1, c2);
System.out.println("El mayor radio es " + c.r +
".")
out.println("Termina main()...");
} // fin de main()
} // fin de class EjemploErrores
class Circulo {
static int numCirculos = 0;
public static final double
PI=3.14159265358979323846;
public double x, y, r;
// constructor
public Circulo(double x, double y, double r) {
this.x=x; this.y=y; that.r=r;
numCirculos++;
}
public Circulo(double r) { this(0.0, 0.0, r); }
public Circulo(Circulo c) { this(c.x, c.y, c.r); }
public Circulo() { this(0.0, 0.0, 1.0); }
public double perimetro() { return 2.0 * PI * r; }
public double area() { retur PI * r * r; }
// mtodo de objeto para comparar crculos
public Circulo elMayor(Circulo c) {
if (this.r>=c.r return this; else return c;
}
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 23/38
// mtodo de clase para comparar crculos
public static Circulo elkMayor(Circulo c, Circulo d)
{
if (c.r>=d. r) return c; else return d;
}
} // fin de la clase Circulo
Compila y ejecuta el ejemplo anterior (copindolo a un fichero). Corrige los
errores que tenga para ver cmo funciona.


Una Ronda de Ejercicios
Este captulo se propondrn una serie de ejercicios de dificultad creciente
basados en todo lo visto anteriormente, a fin de que el alumno afiance los
conceptos del curso.
Sobre los ejemplos
Ejercicio 1:
Modifica las clases anteriores para que muestren la hora actual en lugar del
mensaje "Hola, Java!". Ver paquete java.util, clase Calendar y subclase
GregorianCalendar.
Tipos Bsicos
Ejercicio 2:
Crea un programa java que simplemente muestre por pantalla cual es la
inicializacin por defecto que Java da a cada tipo bsico: boolean, char, byte,
short, int, long, float y double. Utiliza una clase que slo tenga la funcin main
y muestra por pantalla los valores con System.err.println("Tipo " + variable);
Ejercicio 3:
Crea un mtodo que cree e inicialice un array unidimensional del tipo double.
El tamao del array ser determinado por un parmetro de este mtodo y los
valores que se utilizan para la inicializacin estarn dentro de un rango
determinado por dos parmetros del mtodo (inicializar de manera secuencial
incrementando desde el menor al mayor del rango). Crea otro mtodo que
muestre por pantalla el array ya inicializado. Comprueba que estos dos
mtodos funcionan dentro de un programa adicional.
Ejercicio 4:
Modifica el ejercicio anterior para utilizar un array bidimensional.
Ejercicio 5:
Escribe una funcin que realice todas las posibles comparaciones lgicas entre
dos cadenas, incluyendo, equals().
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 24/38
Ejercicio 6:
Escribe un programa que genere 25 nmeros aleatorios y comprueba si estn
por encima o por debajo de un valor intermedio. Almacena los mayores en un
array y los menores en otro array. Muestra los resultados finales por pantalla.
Clases y Objetos
Ejercicio 7:
Crea una clase que se llame MiClase con dos variables miembro.
7.a) Crea un constructor sin parmetros que inicialice las variables miembro
de MiClase.
7.b) Sobrecarga el constructor anterior para que reciba los valores con los que
inicializar las variables.
7.c) Modifica el cdigo del constructor sin parmetros para que utilice el
segundo constructor para inicializar las variables.
7.d) Crea un mtodo toString() dentro de la clase MiClase que devuelva un
String con el valor de las dos variables.
7.f) Compila y ejecuta MiClase. Crea dentro del mtodo main una instancia de
MiClase y llama al mtodo toString().
7.g) Crea un mtodo finalize() que muestre un mensaje por pantalla con
System.out.println("finalize()"). Incluye en el programa las llamadas a los
mtodos System.gc(), System.runFinalizersOnExit(true). Ejecuta para ver qu
pasa.
7.h) Aade una variable publica Static dentro de la clase. Muestra por pantalla
el valor de la variable static en los constructores de la clase. Declara dos
objetos de la clase MiClase e inicializa la variable Static antes, en medio y
despus de instanciarlos (con new).
7.i) Aade una variable del tipo java.util.Collection a la clase MiClase. Inicializa
la variable Collection en los constructores de las clases y aade varios
elementos a la misma. Busca en la documentacin qu mtodos se pueden
utilizar con esta clase y utilzalos dentro de un nuevo mtodo publico
denominado interfaceC. Muestra la salida de cada mtodo por pantalla.
7.j) Crea otra variable de tipo java.util.Vector. Inicializa la variable Vector en
los constructores de la clase y aade unos cuantos elementos al mismo. Busca
en la documentacin qu mtodos se pueden utilizar con esta clase y utilzalos
dentro de un mtodo denominado interfaceV. Muestra la salida de cada
mtodo por pantalla.
Ejercicio 8:
Crea dos clases A y B con constructores sin parmetros que muestren un
mensaje al ser ejecutados. Crea una clase C sin constructor que herede de A y
que tenga una variable de tipo B.
8.a) Crea una instancia del tipo C y observa qu pasa al ejecutar el programa.
(muestra mensajes dentro de los constructores y dnde quieras para
comprobar lo que ocurre).
8.b) Cambia los constructores de la clase A y B para que utilicen un
parmetro. Compila, ejecuta y observa qu ocurre.
Ejercicio 9:
Crea una clase base con dos mtodos. Dentro del primer mtodo llama al
segundo mtodo. Crea una clase hija que redefina el segundo mtodo. En el
programa principal, crea una instancia de la clase hija. Haciendo un casting de
la instancia a la clase base, llama al primer mtodo y explica cual es la salida.
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 25/38
Ejercicio 10:
Crea una clase que contenga una clase miembro (incluida en la anterior) que a
su vez contenga una clase miembro (incluida en sta). Compila y observa los
ficheros que produce el compilador.
Ejercicio 11:
Crea una clase que se llame Perro y que tenga un mtodo sobrecargado
llamado ladrido. Sobrecrgalo de tal manera que el tipo de parmetro determine
el tipo de ladrido. Muestra el tipo de ladrido con un mensaje. Dentro del
programa principal llama al mtodo ladrido con diferentes parmetros.
Interfaces y Packages
Ejercicio 12:
Crea un interfaz perteneciente a un paquete e implemntalo en otra clase de
otro paquete.
Ejercicio 13:
Crea un programa que demuestre que las variables definidas en un interfaz son
static y final y que los mtodos son por defecto pblicos.
Ejercicio 14:
Crea tres interfaces diferentes y demuestra que Java permite la
implementacin (implements) de varios interfaces, que java permite la herencia
multiple de interfaces y que no permite la herencia mltiple entre clases.
Sobre otro Ejemplo (de todo un poco)
Dado el siguiente ejemplo:
//fichero: Forma.java
class Forma {
void dibujar() {}
void borrar() {}
}
class Circulo extends Forma {
void dibujar() {
System.out.println("Circulo.dibujar()");
}
void borrar() {
System.out.println("Circulo.borrar()");
}
}
class Cuadrado extends Forma {
void dibujar() {
System.out.println("Cuadrado.dibujar()");
}
void borrar() {
System.out.println("Cuadrado.borrar()");
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 26/38
}
}
class Triangulo extends Forma {
void dibujar() {
System.out.println("Triangulo.dibujar()");
}
void borrar() {
System.out.println("Triangulo.borrar()");
}
}
public class Formas {
public static Forma formaAleatoria() {
switch((int)(Math.random() * 3)) {
default:
case 0: return new Circulo();
case 1: return new Cuadrado();
case 2: return new Triangulo();
}
}
public static void main(String[] args) {
Forma[] s = new Forma[9];
// Rellenar el array con varias formas:
for(int i = 0; i < s.length; i++)
s[i] = formaAleatoria();
// llamar a los mtodo para ver el polimorfismo:
for(int i = 0; i < s.length; i++)
s[i].dibujar();
}
}
Compila y ejecuta el ejemplo para ver qu ocurre
Ejercicio 15:
Modifica el ejemplo anterior creando una nueva clase denominada pentgono
que herede de Forma y que sobrecargue los mtodos dibujar y borrar. Compila
y ejecuta para ver qu ocurre.
Ejercicio 16:
Crea un interfaz llamado manejo que contenga los mtodos dibujar y borrar y
modifica el ejemplo anterior para que la clase Forma implemente el interfaz
manejo. Compila y ejecuta. qu ocurre?
Ejercicio 17:
Separa cada una de las clases en un fichero diferente y hazlas pblicas.
Elimina de la clase Triangulo el mtodo borrar. Compila y ejecuta para ver qu
ocurre.
Ejercicio 18:
Convierte los mtodos borrar y dibujar a abstractos. Compila y ejecuta para
ver qu ocurre.

2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 27/38

Hebras (Threads)
Una de las principales ventajas del entorno de ejecucin Java es que permite
manejar programas que contienen mltiples procesos llamados Threads. La idea
es crear aplicaciones que puedan realizar a la vez diferentes tareas o, al menos,
hacer creer a los usuarios que se estn realizado varias cosas simultneamente.
Por ejemplo, una aplicacin multithreaded que gestiona un almacn ser capaz de
recibir datos por la red, realizar clculos y a la vez, aceptar la entrada del usuario.
Aunque en realidad slo se ejecutar un thread a la vez, el sistema operativo que
ejecuta el programa va ejecutando durante cierto tiempo un thread y luego saltar
al siguiente thread, pero al usuario le dar la impresin de que se estn
ejecutando todos a la vez.Para entender cmo se codifican los threads, vamos a
ver un ejemplo que contiene un solo proceso. En este ejemplo, el cdigo se
ejecuta de forma lineal hasta que se llega a la ltima lnea, entonces el proceso
termina.
public class Saludo {
// MTODOS
public void saluda (String quien) {
System.out.println (quien + " ha saludado");
}
// MAIN
public static void main (String args[]) {

Saludo presentador = new Saludo();
presentador.saluda ("persona1");
presentador.saluda ("persona2");
presentador.saluda ("persona3");
System.out.println ("Todo el mundo ha saludado");
}
}
La ejecucin comienza y se crea una instancia de la clase Saludo. Luego se llama
tres veces al mtodo saluda(). Cada llamada se ejecuta y luego se devuelve el
control al programa principal. La ltima sentencia del main() escribe "Todo el
mundo ha saludado" y entonces el programa termina. Al introducir los threads en
este programa, se romper la linealidad de la ejecucin. El programa se dividir
en fragmentos y cada uno de los cuales se encargar de escribir el mensaje en
pantalla.
public class Saludo implements Runnable {
// METODOS
public void run () {
System.out.println (Thread.currentThread().getName()
+ " ha saludado");
}
// MAIN
public static void main (String args[]) throws
InterruptedException {
int i = 0;
Saludo presentador = new Saludo();
// Se crea el primer thread
Thread unThread = new Thread (presentador,
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 28/38
"persona1");
// Se crea el segundo thread
Thread otroThread = new Thread (presentador,
"persona2");
unThread.start(); // se inicia el primer thread
otroThread.start(); // se inicia el segundo thread
// Cuerpo del programa principal
while (unThread.isAlive() || otroThread.isAlive())
i++;
// Se ejecuta despus de que los threads hayan
terminado
System.out.println ("El valor de i es " + i );
System.out.println ("Todo el mundo ha saludado");
}
}
Ahora el programa inicia dos threads que se ejecutan concurrentemente a la vez
que el programa principal. Despus de crear los threads, se llama al mtodo
start() de cada uno, lo que le dice al intrprete de Java que comience a procesar
ese thread. El mtodo main() es el responsable de inicializar cada thread y de
determinar cuando termina. Esto es necesario porque el programa necesita saber
cuando es seguro ejecutar la lnea de cdigo:
System.out.println ("El valor de i es " + i );
De otro modo, el programa podra terminar antes de que los threads hayan
concluido, quedando bloqueado. Para controlar esto, se ha puesto un bucle que
incrementa el valor de una variable mientras los threads se estn ejecutando.
while (unThread.isAlive() || otroThread.isAlive()) i++;
Si se compila y ejecuta este programa, se podr comprobar que el valor de la
variable i es diferente en cada ejecucin del programa. Esta variable almacena el
nmero de veces que se ejecuta el bucle while mientras se ejecutan los threads.
El hecho de que este valor cambie, ilustra como Java ejecuta los programas que
se dividen en distintos procesos.

Cundo usar hebras
Lo ms importante de la programacin con threads es conocer cundo se
necesita usarlas. Los threads pueden ayudar a que un programa se ejecute ms
rpido pero tambin pueden entorpecer la ejecucin del mismo. Solamente deben
utilizarse cuando se necesite que dos o ms procesos se ejecuten a la vez. Por
ejemplo, en un entorno de ventanas, se pueden abrir varias ventanas a la vez
para dar la impresin de que varias operaciones estn ocurriendo al mismo
tiempo.
Reiteramos la idea de que cuando una aplicacin se est ejecutando, los distintos
procesos no se ejecutan realmente al mismo tiempo. Es el sistema operativo el
que se ocupa de dar al usuario la impresin de que todo est sucediendo
simultneamente. La mquina virtual Java maneja la gestin del procesador
determinando qu ejecuciones deben ocurrir y en qu orden.

2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 29/38
Cmo se Crea una Hebra
Antes de crear un thread, se debe inicializar una clase que sea la encargada de
manejar el thread. Esto puede hacerse de dos formas: derivando una clase
(haciendo una subclase de la clase Thread) o implementando un interface.
Heredando de Thread
La forma ms obvia de crear un thread es haciendo una subclase de la clase
Thread que proporciona la librera Java. Esta aproximacin permitir sobreescribir
los mtodos de dicha clase para realizar las funciones que sean necesarias en el
programa. Aqu est la sintaxis para crear una clase derivando de la clase
Thread:
[visibilidad] [modificador] class NombreClase extends Thread
// definicin de variables y mtodos
...
}
Vemoslo utilizando este ejemplo.
public class Saludo extends Thread {
// MTODOS
public void run () { System.out.println ("ha
saludado");}
// MAIN
public static void main (String args[]) {
int i = 0;
Saludo presentador = new Saludo();
// Se crea el primer thread
Thread unThread = new Thread (presentador);
// Se crea el segundo thread
Thread otroThread = new Thread (presentador);
unThread.start(); // se inicia el primer thread
otroThread.start(); // se inicia el segundo thread
// Cuerpo del programa principal
while (unThread.isAlive() || otroThread.isAlive())
i++;
// Se ejecuta despus de que los threads hayan
terminado
System.out.println ("Todo el mundo ha saludado");
}
}
Ahora la clase Saludo deriva de la clase Thread y sobreescribe el mtodo run()
definido en esta clase (al heredar Saludo de Thread, contendr todos los
mtodos de Thread como start() y run()). En el ejemplo se mantienen las
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 30/38
versiones originales de los mtodos de la clase Thread excepto en el caso del
mtodo run(), que ha sido redefinido. Dicho mtodo es el que le dice al thread
qu operaciones tiene que realizar una vez que ste ha sido iniciado, por eso
normalmente este mtodo debe ser sobrecargado.
Implementando Runnable
Cuando se disea la jerarqua de clases para la aplicacin, hay veces que es
imposible derivar de la clase Thread (porque las clases ya deriven de otras, por
ejemplo). En estos casos, se puede implementar el interface Runnable para
solucionar el problema. La sintaxis es:
[visibilidad] [modificador] class NombreClase [extends SuperClase] implements
Runnable
// definicin de variables y mtodos
...
}
La ventaja de esta forma es que se puede crear una nueva clase que deriva de
otra clase y adems utilizar los mtodos definidos por el interface Runnable.
public class Saludo implements Runnable {
// MTODOS
public void run () {
System.out.println (Thread.currentThread().getName()
+ " ha saludado");
}
// MAIN
public static void main (String args[]) throws
InterruptedException {
int i = 0;
Saludo presentador = new Saludo();
// Se crea el primer thread
Thread unThread = new Thread (presentador,
"persona1");
// Se crea el segundo thread
Thread otroThread = new Thread (presentador,
"persona2");
unThread.start(); // se inicia el primer thread
otroThread.start(); // se inicia el segundo thread
// Cuerpo del programa principal
while (unThread.isAlive() || otroThread.isAlive())
i++;
// Se ejecuta despus de que los threads hayan
terminado
System.out.println ("El valor de i es " + i );
System.out.println ("Todo el mundo ha saludado");
}
}


Inicializacin de una Hebra
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 31/38
Antes de que pueda utilizarse un thread, debe inicializarse creando una instancia
de la clase Thread. El mejor modo de hacer esto es utilizando el constructor de la
clase Thread. La forma ms simple de este constructor es:
Thread identificador = new Thread();
Otras variaciones de este constructor son:
Thread identificador = new Thread(ReferenciaAObjeto);
Thread identificador = new Thread(Nombre);
Thread identificador = new Thread(ReferenciaAObjeto, Nombre);
El parmetro ReferenciaAObjeto indica la referencia al objeto de la clase que
implementa el mtodo run() y que es el que debe ejecutarse cuando el thread
comience su ejecucin. El parmetro Nombre se utiliza para poner un nombre a
cada uno de los threads por si se quiere distinguirlos. Por ejemplo:
Thread unThread = new Thread (presentador, "persona1");
Thread unThread = new Thread (presentador);
Aunque slo puede iniciarse un Thread cada vez, el orden en que se llaman los
threads no tiene por qu determinar necesariamente el orden en el que terminan.
Volvemos al ejemplo Saludo para ilustrar cmo es difcil de predecir el orden de
ejecucin de los threads.
public class Saludo implements Runnable {
// MTODOS
public void run () {
System.out.println (Thread.currentThread().getName()
+
" ha saludado");
}

// MAIN
public static void main (String args[]) throws
InterruptedException {

int i = 0;
int j = 0;

Saludo presentador = new Saludo();

// Se crea el primer thread
Thread unThread = new Thread (presentador,
"persona1");

// Se crea el segundo thread
Thread otroThread = new Thread (presentador,
"persona2");

unThread.start(); // se inicia el primer thread
otroThread.start(); // se inicia el segundo thread

// Cuerpo del programa principal
while (unThread.isAlive() || otroThread.isAlive()) {

2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 32/38
// Contador del primer thread
if (unThread.isAlive())
i++;

// Contador del segundo thread
if (otroThread.isAlive())
j++;
}

// Se ejecuta despus de que los threads hayan
terminado
System.out.println ("El valor de i es " + i );
System.out.println ("El valor de j es " + j );

System.out.println ("Todo el mundo ha saludado");

}
}
Como los dos threads se crean utilizando el mismo objeto, se pasa un string para
distinguir un thread del otro. En el mtodo run(), el mtodo getName() se utiliza
para imprimir el nombre del thread que se est ejecutando. En este ejemplo se ha
aadido un contador para cada uno de los threads. El planificador contenido en la
mquina virtual Java es el responsable de determinar qu threads pueden
ejecutarse y cuales deben esperar en la cola. Esta decisin puede tomarse de
dos formas: por prioridad o FIFO (First in, First Out. Por orden de llegada a la
cola).

Prioridades
Cuando se procesa un thread, ste se mete automticamente en una cola, en la
que debe esperar hasta que le llegue el turno de ejecutarse. Este proceso de
espera se llama bloqueo.
En la aproximacin FIFO, el thread que est el primero de la cola esperar hasta
que termine el que se est ejecutando y entonces empezar su ejecucin.
En la planificacin por prioridades, en cambio, si un thread tiene una prioridad
mayor que otro le cambiar su lugar dentro de la cola. Este proceso continuar
hasta que se encuentre un thread con una prioridad mayor o igual. De forma que
los threads que estn al final de la cola no se ejecutarn hasta que los de alta
prioridad hayan terminado. El caso ms comn es el caso del thread Garbage
Collector, que tiene la prioridad ms baja.
Para controlar la prioridad de un thread, la clase Thread proporciona las
variables: MAX_PRIORITY, NORM_PRIORITY y MIN_PRIORITY.
Para establecer y obtener la prioridad de un thread se utilizan los mtodos
setPriority() y getPriority().

Vida de una Hebra
Un thread tiene un nacimiento, una vida y una muerte. Durante estos estados, un
thread puede seguir diferentes alternativas dependiendo del objetivo que se
quiera conseguir. Las diferentes etapas de un thread las determina un conjunto
de mtodos predefinidos que pueden sobrescribirse para realizar las tareas
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 33/38
pertinentes.
En las siguientes secciones describiremos cada una de estas etapas, as como
los mtodos y estados destacados.
Creacin
Para crear un nuevo thread debemos llamar al constructor de la clase como se
muestra en el ejemplo siguiente:
public void start () {
if (miThread == null) {
miThread = new Thread(this);
miThread.start();
}
}
Una vez que se crea la instancia tenemos un nuevo thread en estado CREADO.
En este estado el thread es simplemente un objeto thread vaco. An no se ha
reservado ningn recurso del sistema para l. Cuando un thread est en este
estado, lo nico que se puede hacer con l es iniciarlo. Si llamamos a cualquier
otro mtodo se producir una excepcin del tipo IllegalThreadStateExcepcion.
Comienzo
Veamos el mtodo que se muestra en el siguiente ejemplo:
public void start () {
if (miThread == null) {
miThread = new Thread(this);
miThread.start();
}
}
El mtodo start() crea los recursos necesarios para que el thread pueda
ejecutarse, planifica cuando debe comenzar el thread y lanza el mtodo run().
Cuando el mtodo start() termina, el thread pasa al estado RUNNABLE. Si
tenemos en cuenta que muchos ordenadores slo tienen un procesador, es
imposible ejecutar a la vez todos los threads que estn en este estado. Por esta
razn, la mquina virtual Java debe implementar un mecanismo de planificacin
de forma que todos los threads compartan el procesador. Por tanto un thread en
estado RUNNABLE realmente se encuentra esperando su turno para ser
ejecutado en la CPU.
Run [Mtodo]
En este mtodo se definen las acciones que deben realizarse durante la vida del
thread. Por ejemplo:
public void run() {
Thread current = Thread.currentThread();
while (miThread == current) {
try {
Thread.sleep(50);
}
catch (InterruptedException e) {
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 34/38
}
System.out.println ("Sigo vivo");
}
}
El mtodo run() se ejecutar mientras la condicin del bucle miThread == current
sea cierta. Esta condicin de salida se explicar con ms detalle ms adelante.
Por ahora, nos quedaremos con la idea de que esta condicin permitir que el
thread termine correctamente.
Runnable (y Not Runnable) [Estados]
Un thread pasa al estado NOT RUNNABLE cuando se producen uno de estos
eventos:
Se llama al mtodo sleep().
El thread llama al mtodo wait() para esperar a que se satisfaga alguna
condicin.
El thread est bloqueado en un operacin de entrada/salida.
En el ejemplo, el thread miThread pasa al estado NOT RUNNABLE cuando el
mtodo run() llama al mtodo sleep().
public void run() {
Thread current = Thread.currentThread();
while (miThread == current) {
try {
Thread.sleep(50);
}
catch (InterruptedException e) {
}
System.out.println ("Sigo vivo");
}
}
Durante los 50 milisegundos que el thread est dormido (sleep()), no se ejecutar
aunque el procesador est disponible. Cuando haya pasado ese tiempo, el thread
pasar al estado RUNNABLE otra vez y se ejecutar cuando el procesador est
disponible.
Los threads pasan de nuevo al estado RUNNABLE cuando se produzca uno de
los siguientes eventos:
Si el thread est dormido, deben pasar los milisegundos especificados.
Si el thread est esperando una condicin, otro objeto debe informar a
dicho thread de que esa condicin ha cambiado llamando al mtodo notify()
o notifyAll().
Si el thread est bloqueado en una operacin de E/S, dicha operacin debe
terminar.
Sleep [Mtodo]
Este mtodo libera al thread del control del procesador durante una cantidad de
tiempo especificada. La sintaxis de este mtodo es:
Thread.sleep(milisegundos);
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 35/38
En el mtodo run() del ejemplo anterior, se llama al mtodo sleep() para permitir
que se ejecuten otros threads mientras miThread est durmiendo.
Cmo se para un Thread
Un thread muere de forma natural cuando su mtodo run() termina. En el ejemplo
anterior la condicin para el que bucle termine y con l, el mtodo run() es
miThread == current. Esta condicin indica que el bucle terminar cuando el
thread que est actualmente en ejecucin no sea igual a miThread.
public void run() {
Thread current = Thread.currentThread();
while (miThread == current) {
try {
Thread.sleep(50);
}
catch (InterruptedException e) {
}
System.out.println ("Sigo vivo");
}
}
Cuando se quiera parar el thread, alguien debe llamar a al mtodo sleep, (wait(),
stop() tambin se pueden utilizar aunque en algunas versiones de java estn en
desuso) que parar la hebra de forma temporal. De esta forma se le est diciendo
al bucle del mtodo run() que pare durante un tiempo. En estas pausas se puede
modificar alguna variable de control del bucle que es la que debe provocar que el
metodo run() termine de forma definitiva y por lo tanto la hebra desaparezca.
IsAlive [Mtodo]
Este mtodo devolver true si el thread ha sido iniciado y no est parado. Si el
mtodo devuelve false, entonces sabremos que el thread est en estado
CREADO o en estado MUERTO. Si devuelve true el thread estar en estado
RUNNABLE o NOT RUNNABLE.
Yield [Mtodo]
Este mtodo provoca que el thread que se est ejecutando en un momento dado
se mueva al final de la cola para permitir que el siguiente thread sea procesado.
public void run() {
while (miThread != null) {
System.out.println ("Sigo vivo");
yield();
}
}


Compartiendo Objetos
Cuando en una aplicacin existen varios threads ejecutndose a la vez, surge la
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 36/38
necesidad de limitar el acceso a ciertas partes del cdigo donde el acceso
simultneo de varios procedimientos puede provocar un mal funcionamiento de la
aplicacin.
Sincronizacin
Java utiliza la idea de monitores para sincronizar el acceso a los datos. Un monitor
es un lugar protegido en el que todos los recursos protegidos tienen los mismos
bloqueos. Existe solo una llave para desbloquear todos los bloqueos dentro del
monitor y los threads deben obtener esa llave para entrar en el monitor y acceder
a los recursos protegidos. Si muchos threads quieren entrar en el monitor al
mismo tiempo, dado que slo un thread tiene la llave, los otros deben esperar
fuera hasta que el thread que tiene la llave finalice y devuelva la llave a la
maquina virtual Java. Una vez que el thread tiene la llave del monitor, puede
acceder a cualquiera de los recursos que controla el monitor tantas veces como
quiera, mientras posea la llave. Sin embargo, si el thread quiere acceder a los
recursos controlados por otro monitor, debe obtener la llave de ese otro monitor.
En un instante determinado, un thread puede poseer varias llaves y diferentes
threads pueden tener diferentes llaves al mismo tiempo. Cuando varios threads
estn esperando recprocamente las llaves de otros puede producirse el efecto
de interbloqueo o deadlock.
En Java, los recursos protegidos por los monitores son fragmentos del programa
en forma de mtodos o bloques de sentencias encerrados entre llaves. La
palabra clave synchorized se utiliza para indicar que el siguiente mtodo o bloque
de sentencias esta sincronizado por un monitor. Cuando se utiliza el modificador
synchronized en un mtodo, el objeto donde est incluido el mtodo slo puede
ser accedido por un thread a la vez. Cuando un thread entra en una porcin de
cdigo sincronizada, es bloqueado hasta que el thread que est por delante de l
finalice la ejecucin de ese cdigo.
Wait y Notify [Mtodos]
Supongamos que estamos ejecutando un thread dentro de un mtodo
sincronizado y que en la mitad del mtodo se necesita recoger cierta informacin
que proporciona otro thread. Por ejemplo, el primer thread puede abrir un fichero,
el siguiente thread (una vez abierto) puede entrar en el mtodo y escribir algo en
el fichero y para terminar, el primer thread realizar las operaciones de limpieza
necesarias y cerrar el fichero. Esto sera lo ideal, pero si tenemos en cuenta que
estamos en un mtodo sincronizado, slo se permitir que un thread lo ejecute.
Para solucionar esta situacin, se utiliza el mtodo wait(), que provoca que el
siguiente thread entre dentro del mtodo sincronizado. El thread que ha
abandonado el mtodo, puede volver a l cuando se llama al mtodo notify()
desde dentro del mtodo que nos ocupa, volviendo a ejecutar el mtodo desde el
punto donde lo dej.
public synchronized void run() {
int d = 0;

while (d < 100) {
System.out.println (Thread.currentThread().getName()
+ " " + d);
d++;
if (d == 50) {
try {
if
(Thread.currentThread.getName().equals("Thread1")) {
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 37/38
this.wait();
}
}
catch (InterrumptedException e) {
System.out.println ("ERROR");
}
}
}

if
(Thread.currentThread().getName().equals("Thread2"))
this.notify();
}
En este ejemplo, el thread con nombre "Thread1" contar hasta 50. Entonces
abandonar el mtodo y se lo dejar al segundo thread. El thread "Thread2"
contar hasta 99 y notificar al primero para que vuelva a ejecutar el mtodo
desde el punto donde lo dej.

Otra Ronda de Ejercicios
A continuacin se proponen una serie de ejercicios relacionados con el tema de
las hebras, a fin de que los alumnos comprendan totalmente este tema.
Ejercicio 1:
Crea una clase que herede de la clase Thread y redefine el mtodo run() para
que imprima un mensaje y llame al mtodo sleep(). Repite esta operacin 3
veces y despus termina el mtodo run(). Incluye un mensaje en el
constructor y redefine el mtodo finalize() para que imprima otro mensaje
cuando la hebra deje de existir. Ahora crea otra clase que tambin sea una
hebra y que en su mtodo run() llame al System.gc() y a
System.runFinalization() imprimiendo un mensaje cuando se invoque a esos
mtodos. Ejecutar varias veces para ver qu pasa.
Ejercicio 2:
Cambia el ejercicio anterior para que en vez de heredar de las clases,
implementen el interfaz runable.
Ejercicio 3:
Crea tres hebras denominadas, Cliente, Servidor y Coordinador. El
coordinador coordinar la actuacin del Servidor y el Cliente. El Servidor ir
creando tareas que sern almacenadas en un Vector de tareas del Coordinador
y el Cliente ir procesando las tareas del vector de trabajo. La condicin de
parada de las hebras Coordinador y Servidor ser por tiempo y el Cliente
terminar cuando no le quede trabajo restante por procesar.

ltima actualizacin: 27/02/2006
2/7/2014 Curso Bsico de Java
http://geneura.ugr.es/~amorag/cursos/java/ 38/38
Antonio M. Mora Garca
Dpto. de Arquitectura y Tecnologa
de los Computadores (Universidad
de Granada)
Tlfno: 958240838 E-Mail:
Maria Isabel Garca Arenas
Dpto. de Informtica, rea de Arquitectura y
Tecnologa de los Computadores
(Universidad de Jaen)
Tlfno: 953212897 E-Mail:

You might also like