Sei sulla pagina 1di 178

Curso de Java

Curso de Java Gratuito orientado a emuladores de


Lineage Java para la comunidad de Adminspro.





K i m e r a w e b
e m a i l : b r u j u l a t o @ y a h o o . e s
m s n : k i m e r a @ k i m e r a w e b . e s
f b : k i m e r a k i m e r a w e b
1 6 / 0 9 / 2 0 1 2
Kimeraweb
Estas clases gratuitas pretenden abarcar los aspectos
mnimos que hay que conocer para poder programar
en cualquier lenguaje usando como herramienta el
Lenguaje Java. Como modelo usar el emulador L2J.
El curso est dirigido a todos los niveles de usuarios,
desde los que no tienen conocimiento de
programacin a los programadores habituales.










Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 1
El ndice se ir modificando conforme este manual se expanda.
ndice
Tema 1, Introduccin.
1.1 Conceptos de programacin orientada a objetos
1.2 Desarrollo de un objeto
1.3 El cuerpo de un objeto
1.4 Reglas para crear nombres (nomenclatura)
Tema 2, las clases
2.1 Alcance de una clase
2.2 Reglas de declaracin de una clase
2.3 Creando una clase
2.4 La clase abstracta

Tema 3, los mtodos

3.1 Funciones de un mtodo
3.2 Modificadores de acceso
3.3 Modificadores que no dan acceso
3.4 Argumentos de los mtodos
3.4.1 Pasando variables referenciando a objetos
3.4.2 Pasando variables primitivas
3.5 Constructores

Tema 4, las variables

4.1 Variables primitivas
4.2 Variables de instancia
4.3 Variables locales
4.4 Variables de tipo final, transient y volatile
4.5 Variables estticas
4.6 Arrays
4.6.1 Inicializando los elementos en un bucle
4.6.2 Arrays annimos
4.6.3 Arrays primitivos
4.6.4 Array de referencias a objetos
4.6.5 Asignaciones para arrays de una sola dimensin
4.6.6 Asignaciones para arrays de varias dimensiones
Tema 5, Enumeraciones
5.1 Declarando una enumeracin
5.2 Declarando mtodos y variables en una enumeracin

Tema 6, usando las caractersticas de la POO

6.1 La encapsulacin
6.2 Polimorfismo




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 2
6.3 Casteo de variables de referencia
6.4 Implementando una interfaz
6.5 Tipos de retornos en constructores sobrecargados
6.5.1 Devolviendo un valor
6.6 Autoboxing

Tema 7, los constructores

7.1 Construccin, reglas y sobrecargas de constructores
7.2 Encadenamiento de constructores

Tema 8, modificador esttico

8.1 Mtodos y variables estticas
8.2 Mtodos estticos y variables

Tema 9, recolector de basuras

9.1 Funcionamiento del recolector de basuras
9.1.2 Cmo funciona el recolector de basuras?
9.1.3 Puede una aplicacin Java quedarse sin memoria?
9.2 Escribir cdigo que maneje explcitamente objetos elegibles para ser borrados
9.3 Reasignado una variable de referencia
9.4 Aislando una referencia
9.5 Forzando el recolector de basuras
9.6 Limpiar antes de ejecutar el GC - el mtodo finalize()
Tema 10, operadores
10.1 Operadores de asignacin
10.2 Operadores de asignacin compuestos
10.3 Operadores relacionales
10.4 Operaciones de igualdad
10.5 Comparacin de primitivos
10.6 Igualdad para variables de referencia
10.7 Igualdad para enumeraciones
10.8 Comparacin con instanceof()
10.8.1 Errores de compilacin con instanceof()
10.9 Operadores aritmticos
10.9.1 El operador resto %
10.9.2 Operador de concatenacin de cadenas
10.10 Operadores de incremento y decremento
10.11 Operador condicional
10.12 Operadores lgicos
10.13 Operadores e Bitwise
10.14 Atajo para operadores lgicos
10.15 Operadores lgicos sin atajos
10.16 Operadores lgicos ^ y





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 3
Tema 11, Control de flujo

11.1 Estamento if
11.2 Estamento switch
11.2.1 Expresiones vlidas para switch y case
11.2.2 Interrupciones y flujo en los boques switch
11.2.3 El caso default
11.3 Estamento while
11.4 Estamento do while
11.5 Estamento for, o for-in (el bucle bsico)
11.5.1 El for mejorado (para arrays, for each)
11.6 El uso de break y continue
11.6.1 Estamentos sin etiquetas
11.6.2 Estamento con etiquetas

Tema 12, excepciones y aserciones

12.1 El estamento try catch
12.1.1 El uso de finally
12.1.2 Programacin de excepciones no capturadas
12.1.3 Definiendo excepciones
12.1.4 Jerarqua de las excepciones
12.1.5 Manejando una clase completa de la jerarqua de excepciones
12.1.6 Declaracin de Excepciones e Interfaces Pblicas
12.1.7 Relanzando la misma excepcin
12.1.8 Definicin de conceptos, excepcin y error
12.1.9 Programando el arrojo de excepciones
12.2 Mecanismo de aserciones
12.2.1 Reglas de expresin de las aserciones
12.2.2 Aserciones, identificados o palabra clave
12.2.3 Ejecucin con aserciones
12.2.4 Selector para activar y desactivar los assert
12.2.5 El uso apropiado para las aserciones

Tema 13, la clase String, StringBuilder y StringBuffer

13.1 La clase String
13.1.1 String y memoria
13.1.2 Mtodos importantes de la clase String
13.2 StringBuffer y StringBuilder
13.2.1 Mtodos importantes de las clases StringBuffer y StringBuilder

Tema 14, paquete I/O, lectura y escritura de ficheros

14.1 Resumen de las clases I/O
14.2 Creando ficheros, el uso de la clase File
14.3 El uso de FileWriter y FileReader
14.4 Combinando clases I/O, BufferedWriter y BufferedReader
14.5 Ficheros y directorios






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 4
Tema 15, paquete I/O, la serializacin

15.1 ObjectOutputStream y ObjectInputStream
15.2 Objetos grficos
15.3 El uso de writeObject y readObject
15.4 La herencia y la serializacin
15.5 Serializacin y clases estticas

































Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 5
S que queremos hacer cosas ya, pero este manual no va indicado para personas con
inquietudes exprs, es decir, lo leo ya y lo quiero ya. Un buen programador, espero que
cuando acabes el manual lo seas, ha de ser meticuloso y usar todas las reglas aceptadas
universalmente por los programadores, muy importante cuando se trabaja en equipo o se
retoma el trabajo de otra persona, como es nuestro modelo L2J.
En este captulo sabremos que es un objeto, como funciona y reglas de programacin. No te
preocupes, empezaremos a programar tan pronto tengas la base necesaria. Acurdate de que
un gigante con pies de barro...

1.1 Conceptos de la programacin orientada a objetos
En programacin moderna, se usa una estructura llamada programacin orientada a objetos.
Esto no es ms complicado que decir para programar algo haremos uso de otros cdigos que
ya existen.
Entonces, el concepto de objeto: ahora mismo diremos que un objeto es un programa que
podemos incorporar a nuestro cdigo.
En este objeto existen funciones.
Una funcin, tal como su nombre indica es algo que est destinado a hacer, por ejemplo, las
funciones de un coche? Frenar, acelerar, girar...
Ahora imaginemos algo que podramos crear en breve, un formulario.
Funciones de un formulario? Recoger informacin, guardar informacin, recuperar
informacin...
Que podra necesitar el formulario para guardar la informacin al disco? Acceso al disco,
obviamente y... tendremos que crearnos un programa para poder grabar al disco? NO!!
Afortunadamente, todos los lenguajes tienen incluidos objetos bsicos (realmente no son tan
bsicos, se podran escribir miles de pginas... pero de momento lo dejamos aqu) que
usaremos.
Os habis dado cuenta de una cosa? Un objeto que slo sirve para acceder al disco... y nada
ms.










Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 6
1.2 Desarrollo de un objeto
Los objetos en cualquier lenguaje, y Java no es una excepcin, es que deben ser de bajo
acoplamiento y alta cohesin.
Bueno, y esto para qu sirve?
Ojo, si no ejecutas esta premisa a la perfeccin, tu programa va a ser un churro (para que
hablar con rodeos).
Primero, entremos en detalles, que es bajo acoplamiento?
Un programa de bajo acoplamiento significa, que si el programa se modifica, no afectar al
objeto que lo usa. Por ejemplo, imaginemos que tenemos un objeto llamado SUMADOR que
lo nico que hace es sumar dos nmeros. Este objeto se invoca por otro objeto llamado
CALCULADORA. SUMADOR acepta tomar dos nmeros y devolver su suma. Por cualquier
desdicha de la naturaleza, el cdigo de SUMADOR tiene que ser reescrito porque se ha
descubierto un fallo en su programacin. El bajo acoplamiento significa que aun reescribiendo
el cdigo de SUMADOR, CALCULADORA seguir usando a SUMADOR sin tener que editar su
cdigo, resumiendo, SUMADOR es totalmente independiente de CALCULADORA.
La alta cohesin significa que el programa har exactamente y nicamente eso para lo que fue
diseado, y nada ms; de esta manera, sabemos que SUMADOR solo suma, y no har las
funciones de RESTADOR (ms adelante explicaremos otras ventajas).
Con lo explicado aqu, sera censurable que CALCULADORA fuese un objeto que hiciese otra
tarea que no fuese calcular, y que su edicin forzase a que otro objeto que usase
CALCULADORA tuviera que ser editado tambin.
















Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 7
1.3 El cuerpo de un objeto
Un objeto comn, est compuesto de funciones y variables. Explicado brevemente, el objeto
tiene como misin hacer algo, y sus funciones son las tareas que puede realizar.
Hay tareas que necesitan guardar alguna informacin para poder ser realizada, para guardar
esta informacin se usan variables (porque su valor varia al menos, una vez).
Entonces, resumiendo porque esto no tiene ms:
Los objetos contienen funciones y contienen variables.
Las funciones contienen variables.
Al principio cit objeto comn porque ms adelante veremos otra clase de objetos.
























Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 8
1.4 Reglas para crear nombres, o nomenclatura.
Como sabemos cundo leemos un cdigo, si lo que leemos es un objeto, una funcin o una
variable? Es por su nomenclatura (no, no vamos a hacer qumica... todava).
Las reglas para crear nombres son:
Un objeto (tambin se le llama clase) siempre comienza su nombre por maysculas.
Una funcin siempre comienza su nombre por minsculas.
Una variable de clase ir antecedida con el smbolo de guin bajo _, ejemplo _xPos.
Este tipo de variables suelen ser privadas. Las veremos ms adelante.
Las dems variables sern en minsculas.
Aparte de la nomenclatura, los nombres de las clases tienen que ser descriptivas, es decir, su
nombre debe intuir lo que va a hacer, de tal manera, que cualquier lector ajeno al proyecto,
pueda saber, sin leer el cdigo, que es o hace la clase.
Sus mtodos deben ser creados de forma verbal, por ejemplo, las funciones de un coche se
llamarn frenar, acelerar y no freno o aceleracion.
Cuando se quiere obtener o asignar valores, se usan get y set, seguidos del nombre, get
significa obtener, y set, seleccionar. As que si queremos obtener la velocidad del coche,
getVelocidad.
Si lo que deseamos es saber si una operacin se est realizando, usaremos is, que significa en
castellano, ser o estar. Est frenando? -> isFrenando.
Debo decir, que en ingls, queda mejor -> isStopping.
Si estas fijndote, cuando se unen dos palabras, la segunda se pone en maysculas, a esto se le
llama camelCase, y tambin es otra regla que se aplica a todo.
Adems de las clases y funciones, las variables si van a trabajar durante un periodo largo,
tambin han de ser descriptivas, por ejemplo, fuerzaDeFrenado = 100.
Para terminar, las constantes de clase en maysculas, sin usar camelCase, y su lugar, guion
bajo (constante es una variable que una vez asignado su valor, ya no va a cambiarlo) ejemplo:
ANCHO_DOCUMENTO.










Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 9
2.1 Asignar el alcance de una clase
Estos modificadores tambin se pueden aplicar a las funciones y variables.
Cuando creas un objeto, puedes querer que ese objeto, pueda ser usado o no, dentro de su
mbito. Podemos querer que nuestra clase CALCULADORA sea invisible para la clase
INSTRUMENTO MUSICAL y que sea visible para la clase MATEMATICAS por razones evidentes.


Para poder hacer esto, al declarar una clase, podemos hacerlo de diferentes maneras:
Public
Al declarar una clase como pblica, ser visible desde cualquier otra clase situada en
cualquier otra parte.
Sin modificador o Default
Por defecto, una clase es visible en el paquete que se crea nicamente.


Al igual que creamos directorios en Windows (u otro sistema operativo) para agrupar ficheros
que son comunes entre s, o sea, que tienen alguna relacin entre ellos, los ficheros creados en
Java tambin cumplen la misma lgica. En un paquete Musica podramos encontrar los
paquetes Instrumento de Percusion, Instrumento de viento, Instrumento de cuerda, y dentro
de cada uno, mas directorios. Cada directorio se denomina paquete.














Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 10
2.2 Reglas de declaracin de una clase
Antes de crear tu primera clase, an tienes que conocer unas reglas ms, si, lo siento, es
pesado pero necesario, pero no te preocupes, slo con leerlas, te acordars de ellas, porque a
medida que avancemos, vers que son normas evidentes.
Slo puede existir una clase pblica por fichero fuente.
El nombre de la clase siempre ser el mismo que el nombre del fichero que la
contiene.
Si la clase est dentro de un paquete, el estamento package ser lo primero que
aparezca en el fichero de la clase conteniendo su ruta.
Lo siguiente que aparece despus de un package, son los comandos import.
Las instrucciones import y package se aplican a todas las clases del fichero, en otras
palabras, no hay manera de declarar diferentes package para cada clase definida en el
fichero.
Un fichero puede tener ms de una clase no pblica.
Las clases no pblicas del fichero pueden tener un nombre distinto al fichero que las
contiene.

En un package se inserta la ruta de la clase.
Los import se usan para importar otras clases.









Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 11
2.3 Creando una clase
Bien, ya hemos ledo todas las normas habidas y por haber para crear una clase. En estos
momentos somos unos eruditos en lo que a normas se refiere pero ya vamos a empezar la
accin.
Nuestra primera clase va a hacer poco, ya que, como dije antes, la programacin orientada a
objetos se basa en el uso de otras clases para hacer uso de ellas, y como no hemos visto
ninguna, no podemos hacer nada. Est fue una gran leccin, verdad? Nunca la olvidars.
Pero aun sin conocer ninguna clase, podemos crear un pseudo cdigo que tiene como misin
introduciros en el mundo de la programacin orientada a objetos, POO.
Mi primera ilustracin va a consistir en crear un coche y sus funcionalidades.
public class Coche {

public void frenar() { }
public void acelerar() { }

public String getAceleracion() {return null; }
public String getFrenada() {return null; }


}

Que estamos viendo aqu?
Primero, al escribir la clase, se indica su visibilidad. Recuerda que si no se indica, se obtiene un
alcance por defecto, es decir, slo es visible en el paquete que se crea.
Despus tenemos la instruccin class y el nombre de la clase abriendo y cerrando llaves al final
del cdigo, encerrando sus mtodos.
En sus mtodos podemos ver tres palabras que no habamos visto antes, se trata de void,
String y return.
Cuando un mtodo no devuelve nada, al nombre del mtodo le precede la instruccin void.
Cuando un mtodo devuelve algo, le precede el nombre del tipo que devuelve y entre
corchetes la instruccin return seguido de una variable (en este caso, nada, null).
El tipo se refiere a la clase de objeto que va a ser devuelto. Clases de tipos son por ejemplo,
cadenas (conjunto de letras), nmeros, nombres de clases como String, Integer, Object, etc...








Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 12
2.4 La clase abstracta
El nico propsito de una clase abstracta es la de crear un patrn para crear clases del mismo
tipo y funcionalidad que la clase abstracta.
No puede duplicarse.
abstract class Coche {
private double precio;
private String modelo;
private String year;
public abstract void goFast();
public abstract void goUpHill();
public abstract void impresionarVecinos();
}

Cuando creas un coche heredando la clase abstracta Coche, lo que haces es coger un patrn y
asimilarlo a tu cdigo.
Podras pensar que, qu utilidad tiene esto?
Imagina que eres el programador de Coche, y has creado un programa que usa los mtodos
creados en Coche. Otro programador, podra crear un Coche como el tuyo, que adems volase,
pero para que el cdigo ya implementado por ti funcione correctamente en el coche volador,
necesita implementar los mtodos que tu esperas que estn ah, como el precio, el modelo, el
impresionarVecinos... aparte este nuevo programador, hara que su coche volase sin tener que
programar el precio, el modelo, el goFast... que ya estn creados por ti.
Extrapola esto a un NPC de Lineage, si tienes un NPCWalker que quisieras a la vez que vendiera
como un GMShop, que necesitas? Un NPCWalker vendedor, cierto?
Al implementar esto en tu nuevo coche, inmediatamente se incluirn los cdigos necesarios
para que tu clase est correctamente implementada.

Si te fijas, en cuanto heredo CochePlantilla, me exige Add unimplemented methods, aadir
mtodos no implementados. En cuanto pulses ah, se implementarn los mtodos, pero el
cdigo de su interior, es cosa tuya.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 13
Los mtodos marcados como abstractos terminan siempre en punto y coma, en lugar de llaves.
Si el mtodo estuviera en una clase normal, es decir, con cdigo, con tan slo un mtodo
abstracto que tenga una clase, tiene que ser marcada como abstracta tambin.
Cuando una clase abstracta, lo es al 100%, es decir, que no posee ningn cdigo, algo como
esto:

se dice que es una interfaz.
Mientras que en una clase abstracta puedes tener funciones con cdigo y funciones abstractas
mezcladas, en una interfaz no.
Tambin, los mtodos de una interfaz son por defecto pblicos y abstractos, por lo tanto no
tienes que declarar que son pblicos y abstractos. La razn es simple, si el mtodo fuera
privado, cuando heredases la clase abstracta, las subclases no tendran acceso a ellos.

En la interfaz, las variables que puedes crear tienen que ser pblicas (por lo explicado antes),
estticas (que no cambian su valor) y finales (que no pueden duplicarse).
Sin embargo, los mtodos no deben ser estticos, ya que, cuando se hereda la interfaz, los
mtodos abstractos hay que editarlos. Si fueran estticos, no se podran modificar.
Una interfaz puede heredar una o ms interfaces, adems, no puede heredar otra cosa que no
sea una interfaz.
No confundir heredar con implementar, ya que la interfaz no puede implementar nada.
Cuando se declara una interface, debe ser indicado con el modificador interface.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 14
Si quieres que tu interfaz sea accesible desde cualquier parte del cdigo, has de aadir el
modificador public, sino el acceso por defecto (de paquete, default) ser seleccionado.

Aunque sea redundante, puedes usar los modificadores public y abstract para declarar una
interfaz.

En una interface, como dije antes, puedes declarar constantes. Al hacer esto, se garantiza el
acceso a esa variable desde cualquier clase.

Los modificadores que tienes que usar son: public static final, es decir, que son pblicas, que
no varan su valor, y que no se pueden duplicar. Al no poder duplicarse, te aseguras que
ninguna clase tenga acceso a la variable y altere su valor.

Si en cualquier caso olvidases esto, no olvides que, aunque no declares la variable como tal,
ser tomada como public static final irremediablemente:

por lo tanto, al querer modificar la variable:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 15

obtenemos un error que nos comunica que borremos el modificador final de
VELOCIDAD_MAXIMA, y como veis en la captura anterior, no existe tal modificador, es decir,
se hace evidente que JDK nos ha declarado por defecto que es public, static y final.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 16
3.1 Funciones de los mtodos.
Sin los mtodos, las clases no tendran mucho sentido. Los mtodos son los responsables de
que la clase cobre vida, y sentido.
Cuando invocamos una clase, actuamos sobre sus mtodos.
Lo principal que definimos en un mtodo, son las funciones get y set, encargadas de devolver y
actuar sobre las variables de la clase directamente.
Es una buena prctica crear las variables de las clases de forma privada, y manipularlas a travs
de sus mtodos para evitar fallos en su uso. Por ejemplo, podramos usar la clase Coche, y en
su variable VELOCIDAD_MAXIMA, le passemos un valor de cadena en lugar de un valor
numrico, tal como se esperaba. Sin duda, acabara en tragedia:

Para evitar situaciones parecidas, la buena prctica nos obliga a usar un mtodo para prevenir
o evitar errores, porque, en lugar de una cadena de texto, podramos haber pasado como valor
un nmero decimal, pero aun as, sera un valor incorrecto.
Las funciones pueden ejecutar una serie de acciones y devolver un valor, o no devolver nada.
Para indicar que no devuelve nada, despus del modificador, o antes del nombre de la funcin,
indicamos con void nuestra intencin, que traducido significa vaco, es decir, devuelve un valor
vaco.
Cuando queremos devolver el resultado de una operacin, de cualquier clase, entonces el
lugar de void lo ocupa el tipo de objeto que vamos a devolver, una cadena (String), un objeto
(Object) u cualquier otra cosa que hayamos inventado (un Coche por ejemplo).
Para usar el mtodo de una clase, se usa el nombre de la clase seguido por un punto, y luego el
nombre del mtodo. Es como el ejemplo, solo que, una funcin lleva parntesis, y las variables
no llevan.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 17
3.2 Modificadores de acceso
Los modificadores de acceso de los mtodos son cuatro, en lugar de dos como en las clases
(Default y Public) y sus caractersticas son compartidas con las variables.
Si no defines ningn modificador, el modificador por defecto es Default (te lo recuerdo
nuevamente, con Default solo se logra visibilidad dentro del paquete donde se crea).
Public
Cuando un mtodo o una variable se declara pblica puede verse desde cualquier
parte del programa.
Private
Cuando el mtodo o la variable se declara privada, solo es accesible donde es creada.
Protected
Igual que privada, slo que tambin ser accesible por sus subclases.
Default
Por defecto, no estas forzado a declarar una clase Default. Si se omite el modificador,
Default es tomado por defecto.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 18
3.3 Modificadores que no dan acceso.
Estos modificadores se usan para limitar el uso de los mtodos, se les denominan
Nonaccess y hay siete clases.

Final
Se usa para evitar que el mtodo sea sobrescrito en una subclase. Si se pasa
final como parmetro al mtodo, es decir, proporcionarle un valor final, el
mtodo no podr cambiar el valor.


Abstract
Un mtodo abstracto se declara pero no se implementa. En otras palabras, es
un mtodo no funcional. Recuerda que un mtodo abstracto no lleva llaves,
termina en punto y coma. Cuando usas este modificador, lo que buscas es que
la subclase implemente estos mtodos, forzando a definir las acciones que
debe hacer la clase, pero no la manera en que debe hacerlas. As por ejemplo,
nuestro Coche puede obligar a sus subclases a implementar
gastarCombustible, y dependiendo del coche, podra gastar gasolina, diesel,
queroseno, agua, hidrogeno...

Ahora una pregunta de control antes de continuar, podras crear un mtodo abstracto
y final? Piensa en ello, la respuesta ms adelante.







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 19
Synchronized
Indica que el mtodo slo puede ser accedido una vez al tiempo, es decir, que
hasta que la tarea con la primera clase que invoc este mtodo no haya
acabado, pondr en espera a los dems hilos que estn esperando ejecutar
este hilo. Esto es til para una tarea como guardar un fichero. Si se estn
guardando datos, sera un error permitir que otro hilo insertase nuevos datos
mientras se lleva a cabo la operacin de salvar datos. El resultado final es
imprevisible. Las variables no pueden ser declaradas Synchronized.

Native
Este modificador indica que el mtodo se ha implementado desde otra
plataforma de cdigo diferente, normalmente en lenguaje C. Tambin, al igual
que Synchronized, es exclusivo de los mtodos.

Transient
Para entender este, hay que saber primero que es serializar. Cuando se
serializa un objeto, se pretende guardar la informacin que contiene
normalmente en disco. Por ejemplo, el objeto Agenda podra contener objetos
Personas. Si queremos guardar el contenido de la agenda, primero, hay que
serializar el objeto. Bien, pues Transient indica que ese campo no debe ser
serializado por ejemplo, porque sean derivadas de otros campos.

Strictfp
Se usa para asegurar que cualquiera que sea la plataforma donde se ejecute el
programa, la precisin de un nmero decimal sea el mismo. Si se omite, la JVM
usar la precisin que mejor considere.

Static
El ms complejo de usar. Resumir brevemente aunque ser comentado en
profundidad ms adelante.
Una variable esttica es una variable que pertenece a la clase, no al objeto,
quiero decir, una instancia de ese objeto (una instancia, un clon).
Las variables estticas se inicializan una sola vez, al comienzo de la ejecucin
del programa antes que cualquier otra variable.
Un mtodo esttico slo puede acceder a otros mtodos estticos.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 20
Un mtodo o variable esttica es accesible directamente,
NombreClase.NombreMetodo.
Un mtodo esttico no puede usar this o super.
Se puede marcar como static:
Mtodos
Variables
Clases anidadas (no dentro de un mtodo, se ver ms adelante)
Inicializacin de bloques
No se puede marcar como static:
Constructores (ya que se usan para crear instancias)
Clases (a menos que estn anidadas)
Interfaces
Mtodos locales dentro de las clases (lo veremos en detalle)
Mtodos internos de clase y variables de instancia.
Variables locales.

La palabra reservada this se usa para referirse a la variable de la clase, y super a la
variable de la superclase, es decir, la clase de la que se deriva la clase actual.

La respuesta a la pregunta, se puede declarar un mtodo como abstracto y final es... falso.
Ambas declaraciones son opuestas, un mtodo abstracto tiene que ser sobrescrito, recuerda
que se declara sin cdigo, mientras que un mtodo final evita ser modificado.







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 21
3.4 Argumento de los mtodos
Es comn en cualquier lenguaje, que los mtodos acepten parmetros, es decir, en un
objeto, para que se cree una accin, a veces es necesario decirle alguna informacin.
Por ejemplo, si el mtodo fuera, acelerar, una pregunta obvia sera, cunto?
Recordarte antes que nada, que un mtodo se crea primero poniendo su modificador
de acceso (que es opcional, sino se elige, la JVM toma Default), luego el tipo de retorno
que poda ser cualquier cosa (si no quieres ningn tipo de retorno, se escribe void),
seguido del nombre del mtodo y entre parntesis los parmetros.
Pues en Java, la manera ms simple de crear un mtodo es hacer uno que no tome
ningn parmetro:
public class ejemplos {

public void digoHola()
{
System.out.print ("HOLA");
}

}

Explico un poco lo que vemos, primero, la clase, que abre llaves y encierra a un mtodo que no
toma parmetros y se cierran las llaves de la clase.
En el interior de la clase, el mtodo se declara encerrando entre llaves las acciones.
Cuando insertamos un parmetro en el mtodo, debemos decirle a la JVM el tipo de dato que
va a ser insertado. Puede ser cualquier cosa que exista. En este ejemplo, ser de tipo String,
que significa cadena de texto.
public class ejemplos {

public void digoHola(String nombre)
{
System.out.print ("HOLA " + nombre);
}

}

Ahora podemos ver que al ejecutar nuestro ejemplo, nos pedir un nombre para incluir, y que
en el mtodo usaremos ese nombre para incluir en el saludo.








Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 22
Continuemos con el ejercicio y ahora tomaremos la edad como siguiente parmetro:
public class ejemplos {

public void digoHola(String nombre, String edad)
{
System.out.print ("HOLA " + nombre + ", se que tienes " +
edad + "aos.");
}

}

Ahora nuestro resultado sera algo como:
Hola Maria, se que tienes 17 aos.
El cdigo para obtener este resultado sera:
ejemplos.digoHola("Maria","17);

Puedes seguir sumando parmetros hasta que la RAM de tu ordenador se quede sin memoria.
No hay problema.
Si quisiramos hacer una operacin matemtica con la edad, usaramos el tipo int, que
significa, entero, o mejor dicho, nmero entero:

La clase main, que sera la clase que siempre se ejecuta primero por defecto y porque la JVM
busca un mtodo llamado main para ejecutar el programa. Sino existiese ningn mtodo main,
nos lanzara un error.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 23
La consola nos devuelve el resultado de la operacin.


Como colofn de los parmetros hay un argumento denominado var-args, cuando declaramos
como parmetro un var-args estamos diciendo que esperamos un nmero indeterminado de
parmetros.
Este tipo slo se acepta una sola vez en un mtodo y siempre tiene que ser declarado el
ltimo:

Salida de la consola:

Esta forma var args se forma escribiendo tres puntos despus del tipo y en realidad lo que
hace es convertir la variable en un array que se puede recorrer con un for.







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 24
Conceptos nuevos:
Un array es una variable capaz de almacenar ms de un dato.
Este for se denomina foreach porque toma un valor del array y lo introduce en una
variable. Se trata de un bucle que recorre todos los valores almacenados en la variable,
en cada vuelta introduce el valor del array en la variable hasta llegar al ltimo valor.
Un bucle es un bloque de instrucciones que se repite un nmero de veces.

Todo esto se ver ms en detalle.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 25
3.4.1 Pasando variables referenciando a objetos
La memoria en Java se divide en 2 partes, la memoria permanente, Heap, donde viven los
objetos, y la memoria Stack, donde viven las variables.
Cuando pasas un objeto como argumento a un mtodo, debes tener en cuenta que ests
pasando un objeto de referencia, y no el objeto en s mismo. Recuerda que una variable de
referencia almacena los bits que representa (para la JVM) una manera de conseguir ese objeto
en la memoria Heap. Ms importante, tienes que recordar que no ests pasando la variable de
referencia actual, sino una copia. Una copia significa que consigues el patrn de bits de la
variable de referencia, as que cuando pasas una variable de referencia, estas pasando la copia
de bits del objeto que representa. En otras palabras, ambos, el invocador y el mtodo
invocado tendrn ahora una copia idntica de la referencia, pero ambos se refieren
exactamente al mismo objeto del Heap (no a la copia).

3.4.2 Pasando variables primitivas
Cuando una variable primitiva se pasa por un mtodo tampoco cambia de valor, ya que se
pasa una copia de la variable, al igual que ocurre con los objetos.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 26
3.5 Constructores
En un lenguaje orientado a objetos la principal caracterstica es que los objetos se instancian
para obtener nuevos objetos con distinto comportamiento.
Por ejemplo, si creamos un objeto Coche, las propiedades del objeto podran ser, marca,
modelo, potencia y velocidad mxima por poner un ejemplo.
Si a cada modelo Coche, le asignamos una marca distinta, estamos creando nuevos modelos de
coches, al fin y al cabo son coches con distintas caractersticas. No creamos un modelo Ford,
otro Ferrari y otro modelo Porche, sino que creamos estos modelos a partir de un objeto que
rene todas las similitudes de un Coche.
Habiendo aclarado que instanciando un objeto Coche podemos crear nuevos coches con
distintos comportamiento, es hora de explicar la funcin de un constructor.
Cada vez que instancias un objeto, por decirlo de otra manera, un nuevo clon de un objeto,
ests ejecutando un constructor. Si no lo haces t, la JVM lo hace por ti.
La primera cosa que llama la atencin es que un constructor se parece horrores a un mtodo, y
para diferenciar un mtodo de un constructor nos fijamos que el constructor no lleva return ni
lleva void.

Qu vemos aqu? Pues estamos viendo dos clases, la clase pblica Main creando un Ferrari, y
la clase por defecto Coche. Recuerda que un fichero slo puede tener una clase pblica.
Para instanciar un objeto se usa el comando new.
Para convertir la variable Ferrari en una instancia de coche, primero se usa el nombre del
objeto que se va a instanciar, en el ejemplo es Coche, seguido de la variable, y luego usando
new (traducido significa nuevo, nuevo Coche) seguido del objeto que queremos instanciar (o
clonar, como lo veas ms claro) y entre parntesis, las opciones del constructor.
Si el constructor no existiese, la JVM implementara (aunque no aparecer en el cdigo):
public Coche (){}




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 27
Ahora veamos el cdigo del Coche:

La variable de la clase, tal como indicamos antes, por el convenio de Java, se escribe en
maysculas y los espacios separados mediante guin bajo, MARCA_DEL_COCHE.
Luego tenemos el constructor, el nombre es el mismo que el de la clase, Coche, y su funcin es
la de asignar la variable de la clase la marca del coche, de esta manera, cada vez que
instanciemos un Coche, tendremos una marca.
Luego tenemos un mtodo coche, respetando el convenio de Java para los mtodos, el
formato del nombre es camelCase. Pero aun respetando el convenio, es una mala prctica
nombrar un mtodo con el mismo nombre que su clase, porque slo es til para crear
confusin, como es este caso. La funcin de este mtodo es imprimir en pantalla la marca del
coche pasada por parmetro.
Hay una tcnica de programacin que se llama sobrecarga de mtodos, consiste en crear
mtodos con el mismo nombre pero aceptando diferentes parmetros.

Por ejemplo, aqu declaro dos constructores, el primer constructor (lnea 13) construye un
coche sin parmetros, en la lnea 14 construye un Coche con la MARCA_DEL_COCHE.













Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 28
Ahora completemos lo que sera un Coche:

Este cdigo es algo ms completo definiendo el Coche.
En la clase Coche ahora hay cuatro propiedades en lugar de una. Tambin tenemos un
constructor que toma dos parmetros de tipo String (cadena de texto) y dos ms de tipo int
(nmeros enteros). Para completar, aadimos un mtodo para obtener la informacin del
Coche, respetando siempre el convenio de Java, usamos get como parte del nombre
(traducido significa obtener).
Ahora, al instanciar un Coche, tendremos que introducir toda la informacin que el constructor
de la clase est esperando, sino, nos dar error y no nos dejar compilar. As que la clase
pblica Main instancia un Coche pasando cuatro parmetros en lugar de dos. Si te fijas, los
parmetros que no son cadenas de texto, se pasan sin usar comillas. Slo las cadenas de texto
se rodean con comillas.









Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 29
Ahora hagamos dos coches y probemos el resultado.

La consola arroja:

la especificacin de los dos coches. Como ves, el usar un objeto con diferentes propiedades da
como resultado nuevos objetos con diferentes comportamientos. Esto es la programacin
orientada a objetos.














Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 30
4 Las variables
Decamos antes que las variables son palabras que guardan un valor, y el nombre de la variable
debe ser significativo, para relacionar de forma humana lo que guarda.

4.1 Variables primitivas
Hay ocho tipos de datos primitivos en Java, son:
char: es un carcter, su rango va desde el 0 al 65,535
boolean: es un 0 o un 1, se usa para indicar si una condicin es falsa o verdadera.
byte: almacena un valor entre -128 al 127.
short: almacena un valor entre -32,768 y 32,767.
int: almacena un valor entre -2,147,483,648 y 2,147,483,647.
long: almacena un valor entre -9,223,372,036,854,775,808 y 9,223,372,036,854,775,807
float: almacena un valor entre 1.40129846432481707e-45 y 3.40282346638528860e+38
double: almacena un valor entre 4.94065645841246544e-324d y
1.79769313486231570e+308d
Aunque para nuestros efectos, usaremos normalmente float.
Esto slo es a ttulo informativo, no tendrs que aprendrtelo de memoria, aunque si tendrs
que aprender bien boolean e int, que son los ms usados.
Si prefieres aprendrtelo de otra manera, a m me gusta ms esta:










Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 31
4.2 Variables de instancia
Las variables de una instancia (no de una clase), se definen dentro de una clase pero fuera de
cualquier mtodo, y se inicializan cuando se inicializa la clase.
Qu diferencia hay entre una variable de clase y otra de instancia? La variable de clase no se
instancia, es decir, no se puede clonar con new.
Muy importante es recordar que las variables de instancia pueden usar cualquiera de los
cuatro niveles de acceso (te acuerdas? public, private, default y protected) y que pueden ser
marcadas como final y transient.
No puedes declararlas como abstract, synchronized, stricfp, native y por supuesto, static.
Para entender variable de clase y variable de instancia, he modificado el cdigo:

Fjate que en la variable de instancia, cada modelo de Coche tiene sus propias caractersticas,
pero al poner como esttica una de las variables, automticamente se transforma en variable
de clase, y al asignarle un valor al Ferrari, tambin se le asigna el valor al Toyota, de manera
que cuando se ejecuta:

Obtenemos:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 32
4.3 Variables locales
Las variables locales se encuentran en los mtodos, viven y mueren dentro de el, y se
destruyen cuando el mtodo ha terminado su tarea.
Las variables locales slo pueden ser marcadas como final.
Al contrario que las variables de clase, las variables locales para poder usarlas, es necesario
inicializarlas primero, es decir, asignarle un valor.
Que es declarar una variable? Decir que existe sin que contenga un valor, por ejemplo:

Que es inicializar una variable? Asignarle un valor (aunque sea un valor vaco).

Tambin puedes inicializar la variable cuando la declaras:

El resumen de los modificadores que puedes usar:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 33
4.4 Variables de tipo final, transient y volatile
El modificador final hace imposible reiniciar la variable una vez que se ha obtenido un valor
explcito (que es distinto que un valor por defecto, como ocurre con las variables de clase).
Acurdate que una clase final no puede heredarse, un mtodo final no puede sobrescribirse en
una subclase y una variable final, no puede modificar su valor.
El modificador transient sirve para decirle a la JVM que ignore la variable cuando se quiere
serializar el objeto o deserializarlo. Cuando de/serializas un objeto lo que haces es
recuperar/almacenar la informacin (del/en disco duro por ejemplo). Este recurso tan
interesante ser visto ms adelante en profundidad.
El modificador volatile le dice a la JVM que el hilo que accede a la variable debe obtener su
propia copia. Esto se usa en procesos multihilos, donde cada hilo de ejecucin podr variar el
valor de la variable. Profundizaremos en esto ms adelante, ahora solo tienes que saber que
existe para ser usados en programacin multihilos.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 34
4.5 Variables estticas.
El modificador static se usa para crear variables estticas. Una variable esttica pertenece
siempre a la clase donde se crea, no a sus instancias (o clones). Como vimos en el ejemplo
anterior, al crear una variable esttica en la clase Coche, su valor cambiaba en todas las
instancias creadas con Coche, en el ejemplo, al cambiar el valor en Ferrari, Toyota tambin fue
afectado.

4.6 Arrays
Los arrays son variables de tipo objeto porque son capaces de guardar mltiples valores o
variables al mismo tiempo. Pueden almacenar datos primitivos o referencias a objetos. Esta
clase de variables viven en el Heap.
Los arrays se declaran comenzando por el tipo de elemento que el array va a almacenar,
puede ser un objeto o datos primitivos seguidos de llaves cuadradas, luego le seguira el
nombre de la variable.
Aunque podramos poner los corchetes al final, resulta menos legible.
Si colocamos ms corchetes, estamos creando dimensiones.

Podemos hacer cosas absurdas como esta, aunque tambin son vlidas:

Esto es lo mismo que poner dos corchetes juntos.
En la declaracin nunca se pone el tamao al contrario que ocurre con otros lenguajes, que se
puede iniciar el array declarando la cantidad de slots disponibles en el array.
Quiero decir, esto, es ilegal:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 35
La forma ms directa de construir un array es usando new seguido del tipo del array.

En este ejemplo hemos creado 11 slots para guardar cadenas de texto en la variable nombre.
Digo 11 porque se cuenta a partir del cero, si contamos el cero y el diez, tenemos once slots.
Cuando se inicializa una variable, por defecto, en los slots encontraremos los valores por
defecto del objeto. Para una cadena es nada, para un nmero es cero, y para objetos es null.
Null no significa que nulo, no es un error, como en otros lenguajes, significa que no guarda
ninguna referencia a ningn objeto.
En los arrays dimensionales podramos decir que son arrays de arrays (en caso de arrays de
dos dimensiones), es como imaginar el juego de hundir la flota. Si declaras una variable de 10 y
10, imagnate un eje X de 10 posiciones y un eje Y de 10 posiciones (10 x 10), son 100
posiciones de memoria reservadas.
Los arrays de dos dimensiones pueden ser declarados de las siguientes maneras:

Es decir, puedes inicializar la cantidad de slots en cada dimensin del array.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 36
4.6.1 Inicializando los elementos en un bucle
Un bucle es un bloque de instrucciones que se repite mientras se cumple una condicin.
Veremos las diferentes clases que hay en profundidad.
Los objetos de un array tienen solo una variable pblica que devuelve el nmero de elementos
del array. El ltimo valor del ndex es siempre uno menos que la longitud del array. Esto se
debe a que la posicin cero del array se cuenta en la longitud.
As que, array[3] es array.lenght = 4, suponiendo que haya un elemento en cada slot del array.
La forma ms sencilla de recorrer un array es usar el for de tipo foreach (sera la forma que
correspondera a otros lenguajes, en Java no hay distincin).

Lo que vemos aqu es que se ha declarado un array llamado numeros con 11 slots.
El bucle es for y encierra entre llaves la repeticin de instrucciones.
Dentro de for se declara a para que acepte cada elemento guardado en numeros.
Inicializamos cada slot con el valor guardado en slot, que en cada repeticin del bucle suma
uno (slot++). As que en cada bucle, se est eligiendo un slot para asignarle un valor
(numeros[slot]=slot).





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 37
O sea, esto est haciendo:
numeros[0] = 0
numeros[1] = 1
numeros[2] = 2
etc, hasta llegar al ltimo slot del array, el 9. Recuerda, del 0 al 9 son 10 slots.
Otra manera es usando la antigua versin de for y la variable len del array.

Lo que estamos viendo aqu es que en el for se inicializa la variable x con el valor de cero.
En segundo lugar se especifica la condicin que mientras sea cierta, ejecutar el bloque de
instrucciones, esta es que x sea menor que la longitud de numeros.
Finalmente, le sumamos a la variable x un uno.
Dentro del bucle se iguala la variable numeros con el ndice x al valor de x.
Es exactamente el mismo proceso que el anterior, slo que aqu el final del array lo conocemos
porque hacemos uso de la propiedad length del array. En for actualizado, esto se hace de
forma automtica, el bucle se detiene porque conoce el ltimo elemento.
Otra manera de declarar e inicializar un array es asignarle los valores en la misma lnea:

Al hacer eso, ya le hemos dicho al compilador que nuestro array tendr 10 elementos.
Se pueden crear los elementos in situ:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 38
4.6.2 Arrays annimos
La otra manera de crear e inicializar un array se la conoce como array annimo. Esto sirve para
crear un array justo en el momento de su uso, por ejemplo, para drselo a un mtodo que lo
coja como parmetro. El array se crea sin variable de referencia.


4.6.3 Arrays primitivos
Los arrays primitivos pueden aceptar cualquier valor que pueda ser promocionado
implcitamente al tipo declarado en el array. Por ejemplo, un array de int, puede almacenar
cualquier tipo de datos que pueda albergarse en 32bits. As que el siguiente cdigo es vlido:


4.6.4 Array de referencias a objetos
Si el tipo de array es una clase, puedes poner objetos de cualquier subclase del tipo declarado
en el array. Por ejemplo, si Subaro es subclase de Coche, puedes ponerlo tal como se muestra
en el ejemplo:

Esto ayuda a recordar que los elementos en un Coche son solo variables de referencia a Coche.
As que cualquier cosa que pueda ser asignada a Coche, puede ser asignada a un array de
elementos de tipo Coche.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 39
Si el array es declarado como un tipo de interfaz, los elementos del array pueden referirse a
cualquier instancia de cualquier clase que implemente la interfaz. El siguiente cdigo
demuestra el uso de una interfaz en un array:


4.6.5 Asignaciones para arrays de una sola dimensin
No estamos hablando sobre referencias en el array (en otras palabras, array de elementos),
sino ms bien una referencia al array. Por ejemplo, si declaras un array int, la variable de
referencia que declaras puede ser reasignada a cualquier array int (de cualquier tamao), pero
no puede ser reasignado a cualquier que no sea un array int, incluyendo el valor int.
Recuerda que todos los arrays son objetos, as que una referencia a un int no puede referirse
a un nmero int. El siguiente cdigo muestra asignaciones vlidas y no vlidas para arrays
primitivos:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 40
Es tentador suponer que porque una variable de tipo byte, short, o char puede ser
explcitamente casteada y asignada a un int, un array de cualquiera de los tipos podra ser
asignado a un array int.
No puedes hacer eso en Java.
Los arrays que almacenan referencias a objetos, lo opuesto a datos primitivos, no tienen
restriccin. As como puedes poner un Honda en Coche (porque Honda hereda Coche), puedes
asignar un array de tipo Honda a una variable de referencia tal como sigue:

Aplica el test ES-UN para distinguir lo que se puede de lo que no se puede hacer. Honda ES-UN
Coche, as que el array de Honda puede ser asignado al array Car. Beer ES-UN Coche, no es
cierto, no hereda Coche, as que no es vlido.
Las reglas de los arrays se aplican por igual a las interfaces como a las subclases. Un array de
interfaces, puede referenciar un array del tipo que haya implementado la interfaz. Recuerda
que cualquier objeto de una clase que implementa una interfaz particular pasara el test de ES-
UN. Por ejemplo, si Box implementa Foldable, lo siguiente, es vlido:


4.6.6 Asignaciones para arrays de varias dimensiones
Cuando asignas un array a un array ya declarado, el array que asignas debe ser de las mismas
dimensiones que las referencias que estas asignando.
Por ejemplo, un array de dos dimensiones de int no se le puede asignar a un int normal, tal
como sigue:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 41
Presta una atencin en especial a la asignacin de los arrays usando dimensiones diferentes.
Podras por ejemplo, confundirte al asignar un array int al primero elemento de un array de
int, como sigue:

Puedes inicializar los bloques que quieras en una clase. Lo importante a tener en cuenta, es
que, al contrario que los mtodos o constructores, el orden en el que los bloques aparecen en
la clase, si importa.
Cuando es la hora en que tienen que ejecutarse los bloques, si la clase tiene ms de uno,
empezaran a ejecutarse en el orden en que aparecen la clase... en otras palabras, desde arriba
hacia abajo.
Acurdate de estas reglas:
Los constructores se ejecutan en el orden en que aparecen.
Los bloques estticos solo se ejecutan una vez, cuando la primera clase se haya
cargado.
Las instancias de los constructores se ejecutan cada vez que la clase se instancia.
Las instancia de los constructores se ejecutan despus de la llamada a super().

Este cdigo:



tendr esta salida:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 42
Como puedes ver, las instancias de los bloques init se han ejecutado dos veces. Instanciar los
bloques init son a menudo usadas en lugar de poner todo el cdigo en los constructores en la
clase que deberan compartir.
De esa manera, el cdigo no tiene que estar duplicado a travs de los constructores.
Finalmente, si haces un error en tu bloque esttico, la JVM puede arrojar un
ExceptionInInitalizationError.
Veamos un ejemplo:

producira un error como:

Los bloques estticos se ejecutan antes, sin importar si estn despus:

Este cdigo dar como resultado:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 43
5.1 Declaracin de una enumeracin
Una enumeracin se usa para minimizar an ms los riesgos de equivocacin en un grupo de
trabajo. Esta es una buena prctica, adems que facilita la lectura del cdigo.
En Java se puede restringir una variable para tener unos valores predefinidos, a esto se le
llama lista enumerada o enumeraciones.
Digamos por ejemplo que tenemos varios tipos de coches que podemos tener, deportivos,
turismo y comerciales. Para evitar que otro programador intente obtener un coche que no
existe, digamos 4x4, se restringe los valores de la enumeracin a los que tengas creados.
Declarar una enumeracin es tan fcil como esto:

Respetando el convenio de Java, se presentan en maysculas.
El uso es igual de sencillo, adems, cuando declaras una enumeracin, el editor (yo uso
Eclipse) te ayuda mostrando las opciones disponibles:








Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 44
De tal manera que la nica forma de conseguir coches ahora es usar las opciones que nos deja
disponible la enumeracin:

Los componentes bsicos de una enumeracin son sus constantes. Pueden ser declaradas
como clase propia (como en este ejemplo), miembro de una clase, pero no pueden ser
declaradas dentro de un mtodo.
As se declara como miembro de una clase:

Acurdate que slo puede existir una clase pblica por fichero.
Esto sera miembro de una clase:

Es posible que encuentres la declaracin de una enumeracin terminando en ; esto es
opcional.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 45
Bueno, y una vez que tengo una enumeracin, que hago?
Antes hay que explicar un poco ms. Una enumeracin no es un tipo String o int. Cada
miembro de una enumeracin es una instancia de la misma (o sea, un nuevo clon). As que
DEPORTIVO no es slo una constante de la enumeracin, es un tipo de TiposDeCoches. Es
decir, al igual que un tipo es un String o un int, pues acabamos de crear tres tipos nuevos de
TiposDeCoches.
Una enumeracin es como una clase, la diferencia es que a cada valor le corresponde una
instancia de la enumeracin, donde la instancia es esttica y final, es decir, no se puede editar
su valor, ni se puede hacer una subclase de ella (usar la palabra new) as que realmente se
tratan como de una constante.
A cada valor de la enumeracin le corresponde un orden de indexado, es decir, la enumeracin
sabe en que orden estn los tipos de coche.
Ms adelante profundizaremos en este tema, de momento tienes que saber que existe y cmo
funciona bsicamente.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 46
5.2 Mtodos y variables en una enumeracin
Una enumeracin adems de declarar tipos estticos y finales, puede ejecutar acciones al igual
que una clase, es decir, podemos usar mtodos y variables, y algo raramente conocido como
cuerpo de clase constante especfica. Esto es til por ejemplo, si quieres aadir una propiedad
a los tipos, como por ejemplo, el nmero de puertas (por decir algo):

Bien, no te asustes, es sencillo y te lo voy a explicar. A cada tipo le hemos asignado un nmero,
presumiendo que representan el nmero de puertas de cada tipo de coche. Pero para poder
usar estos nmeros es necesario crear un constructor, ese constructor, al igual que en las
clases, tiene el mismo nombre que la clase donde se crea. En nuestro caso acepta un
parmetro de tipo int que se recoge del valor guardado en el tipo, es decir, nuestro
constructor acepta un nmero que representa la cantidad de puertas del tipo de coche.
Al igual que las clases, he incluido un mtodo para saber cuntas puertas tiene ese vehculo,
getPuertas.
No puedes olvidar que en el constructor no se puede invocar directamente. Se convoca
automticamente con los argumentos que defines en las constantes. Por ejemplo
DEPORTIVO(3) invoca al constructor y le pasa el parmetro 3. Esto lo habrs adivinado, y si no
es as, es que necesitas practicar esto un poco. Coge Eclipse (u otro editor) y practica un poco.
Al igual que en las clases, puedes sobrecargar el constructor, es decir, crear ms de uno.
Tambin puedes hacer cosas extraas, como que parezca una clase annima interna (este tipo
de clases la veremos ms adelante), se conoce como cuerpo de constante especfico y se usa
cuando necesitas una constante para definir un mtodo definido en la enumeracin.
Lo veremos ms claro con un ejemplo.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 47
Imaginemos que necesitamos devolver el tipo de combustible del coche, por defecto son todos
gasolina pero el comercial sera diesel.

Puedes fijarte que a la enumeracin se incluye getCombustible, pero en COMERCIAL se han
abierto unas llaves donde se define el mismo mtodo, es decir, lo est sobrescribiendo.
Mientras que para el DEPORTIVO y el TURISMO el combustible devuelto ser gasolina, el
COMERCIAL devolver diesel.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 48
6.1 Encapsulacin
La encapsulacin consiste en el acceso a las variables de la clase mediante un mtodo en lugar
de hacerlo directamente. Bueno, y esto para qu sirve?
Imagnate que estas creando un cdigo donde ests trabajando con un puado de personas,
que no conocen las clases que has hecho, y la misma situacin es la tuya, tu no conoces su
trabajo aunque estis participando en el mismo proyecto, te va sonando L2J?
Si accedieses directamente a las variables podras pasarle tipos errneos.
Que es un tipo?
Un tipo es cada clase creada para trabajar con ellas, cada objeto que se crea o existe en Java,
es un tipo.
Otra ventaja es el mantenimiento del cdigo. Si en tu cdigo hubiera que corregir el cdigo y
otro programador usase tu clase mediante los mtodos de la clase, este programador no
necesitar saber siquiera los cambios que hagas en tu programa, no se enterar.
Por ejemplo:

Aqu tenemos el hipottico caso en que un programador ha creado la clase Arma, y otro
programador que la est usando. Como vemos, puede declarar un Arma con una potencia
infinita. Si Coder crease un arma con potencia cien millones y resultase que esa arma
descompensase el server (porque el jugador se hiciese invulnerable, por ejemplo), habra que
arreglar este bug!





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 49
Como arreglar este bug sin que Coder tenga que editar su cdigo? Bien, pues Magneto lo
nico que tiene que hacer es limitar la potencia del arma:

Magneto rescribe su cdigo, si la potencia es mayor de 100, entonces la potencia es 100. De
esta manera Coder no tiene que editar su cdigo, ni se ha enterado, l sigue haciendo lo suyo
sin tener que mirar tu cdigo.
Los beneficios que recibes pensando en POO es flexibilidad y mantenimiento.
La habilidad de hacer cambios en tu cdigo sin romper el cdigo de otros programadores es la
clave de la encapsulacin.
Cuando creas una serie de mtodos accesibles desde otras clases (y manteniendo tus
implementaciones ocultas para proteger tu clase), estas creando APIs.
Para conseguir mantenimiento, flexibilidad y extensibilidad debes seguir estas premisas:
Las variables de la instancias deben estar protegidas, el modificador de acceso
normalmente, privado.
Crea mtodos de acceso pblico para forzar a otros programadores a acceder
directamente a los mtodos en lugar de a las variables.
Usa la convencin de JavaBeans, setNombreMetodo, getNombreMetodo.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 50
Veamos ejemplos:

Como habamos dicho antes, las variables de instancia han de ser privadas, de tal manera que
el programador no pueda acceder directamente a ella.
Ahora la nica manera de seleccionar la potencia del arma es mediante el mtodo
setPotencia.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 51
Encapsulada la variable de clase y protegiendo el exceso de potencia mediante nuestro cdigo,
an tenemos un posible error que controlar, os pongo el cdigo:

El error es que Coder an podra crear un arma con potencia -100, pero te diste cuenta
demasiado tarde, ya estn usando el programa.
Vas a decirle a Coder que ha ingresado un valor negativo para el arma y que la gente se est
quejando porque su arma no mata sino que cuenta chistes?





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 52
NO! Magneto rescribe su cdigo gracias a que ha hecho uso de la encapsulacin.

y Coder ni se entera.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 53
6.2 Polimorfismo
El polimorfismo es la posibilidad de que una clase hereda las caractersticas de otra clase para
crear una nueva.
La clave para usar de buena forma el polimorfismo es preguntarte ES UN?
Ejemplo, creamos la clase Coche, y luego creamos Ferrari heredando las caractersticas de
Coche. Como saber si lo estamos haciendo bien? Plantate la pregunta, Es un Ferrari un
Coche? La respuesta es SI.
Ahora creas la clase Mercedes heredando las caractersticas de Ferrari. Ambos son coches,
parece estar bien, pero si te preguntas Un Mercedes es un Ferrari? La respuesta es NO, as
que estas liando los objetos.
Con este truco jams te equivocars. Recuerda, ES UN.
Para usar esta caracterstica usamos la palabra clave extends.
En que consiste la herencia?
La herencia consiste en heredar todas las propiedades de una clase. La utilidad de esto es que
aadiendo nuevas propiedades creas nuevos objetos.
Ejemplo, la clase Coche lleva ruedas, puertas, frenos, motor.
La clase Ferrari lleva adems de lo que lleva un Coche, un caballo como smbolo, el constructor
es Minielli y el diseador es Montiveri (por decir cualquier cosa).
La clase Spider que hereda a Ferrari, adems de lo que lleva Ferrari, y de lo que lleva un Coche,
mide 5 metros y alcanza los 295Km/h.
Podramos sacar una nueva clase de Ferrari heredando Ferrari, o podramos sacar un Coche
nuevo como Mercedes heredando Coche, o incluso podramos sacar un
CocheVoladorSubmarino heredando Coche y aadiendo las caractersticas de un coche que
vuele y se sumerja.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 54

En este ejemplo vemos cmo se crea Coche, CocheVolador y CocheVoladorSubmarino, donde
CocheVolador aparte de tener alas y flaps propias de un avin, hereda rueda, frenos, puertas
y chasis. Ms complejo aun es el CocheVoladorSubmarino, que aparte de llevar timn, vela y
mastil propias de un barco, lleva alas y flaps del CocheVolador, y como el CocheVolador
hereda Coche, CocheVoladorSubmarino tambien hereda ruedas, frenos, puertas y chasis.
Aparte de sus variables de instancia, tambin heredarn sus mtodos, como podra ser
frenar() (para el Coche), despegar() (para el coche volador) e inmersin() (para el coche
volador submarino).
Y si quisiera hacer un CocheTanque? Pues... heredara las propiedades de un Coche y le aado
las caractersticas de un Tanque.
La nica manera de acceder a un objeto es a travs de una variable de referencia, es decir, la
variable que usas con new, en el ejemplo podemos ver que mi referencia a un coche volador
submarino es DelfinConAlas.
Tienes que saber que la variable de referencia slo puede ser de un slo tipo, es decir, aunque
DelfinConAlas es el resultado de la herencia de un Coche y de un CocheVolador, el tipo es
CocheVoladorSubmarino y nada ms.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 55
A la variable de referencia le puedes asignar otros objetos, a menos que sea declarada como
final. Es decir:

Una variable de referencia tambin puede referirse a cualquier objeto del mismo tipo
declarado en la referencia, incluso puede hacer referencia al subtipo declarado.

A esto se le llama casteo que lo veremos en profundidad. En el ejemplo vemos que declaro un
CocheVoladorSubmarino donde la variable de referencia est referida a un CocheVolador.
Como es del mismo subtipo, el compilador no lanza error y lo acepta como correcto.
Una variable de referencia tambin puede ser declarada como un tipo de clase o un tipo de
interfaz. Si se declara como un tipo de interfaz puede referenciar cualquier objeto de cualquier
clase que implemente la interfaz.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 56

En el ejemplo la variable de referencia est declarada como interfaz Frenar pero se inicializa
como CocheVoladorSubmarino, ya que CocheVoladorSubmarino implementa la interfaz
Frenar.
Al implementar una interfaz (lo habamos visto antes) se deben implementan los mtodos
declarados, pero el cdigo de los mtodos abstractos tiene que ser escrito por ti.
Fjate que la nica clase que implementa los mtodos es Coche, CocheVolador y
CocheVoladorSubmarino no lo escriben. Eso es, como ya dije antes, que heredan sus mtodos,
y no hace falta volver a escribirlos. Es ms, si se rescriben, estaras sobrescribiendo los
mtodos de la clase que se hereda, o sea, creando unos nuevos. Esto est bien cuando el
cdigo del mtodo no es suficiente para la clase que lo hereda.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 57
6.3 Casteo de variables de referencia
Como hemos visto en el tema anterior, un casteo consiste en cambiar de un tipo a otro tipo,
siendo el otro tipo un subtipo, es decir, un casteo de Ferrari a Coche es posible, pero no uno
de Ferrari a CocheVoladorSubmarino.
Es un Ferrari un CocheVoladorSubmarino?
NO! Acurdate siempre de este truco.
En el casteo existen dos direcciones, subir en la escala de la herencia, que se denomina
upcasting y el compilador funciona explcitamente (es decir, no tienes que indicarle que ests
haciendo un casteo) y bajar en la escala de herencia, denominado downcasting, donde si
tienes que indicar explcitamente el casteo.
Ejemplo:

Aqu vemos que se declara c1 como Clase1 y se hace un casteo a la Clase4. Como la herencia es
ascendente, no hace falta indicar expresamente el casteo.
Pero al hacerlo al revs (downcasting):

el compilador se queja, indicar el casteo se hace obligatorio.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 58
Pero, qu pasa si una vez casteado, queremos usar el mtodo de otro tipo?

El casteo ahora est hecho correctamente, el compilador est feliz por la aclaracin, pero al
ejecutar el programa, sorpresa...

Por qu ocurre esto? Por qu el compilador no nos ayuda y ver que Clase1 y Clase4 son del
mismo subtipo? El compilador lo nico que puede hacer es confirmar que ambos tipos
pertenecen al mismo rbol de la herencia.
En un upcasting, el nmero de mtodos se restringe, as que no existe la posibilidad de que un
mtodo de una clase se haya sobrescrito, al contrario que ocurre con un downcasting. El punto
es que ninguna referencia de tipo Clase4 puede hacer llamadas seguras a una instancia de
Clase1.
Ojo, con esto no digo que el downcasting est prohibido. Si el compilador ve que hay
posibilidad de que en tiempo de ejecucin funcione, compilar.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 59
En este ejemplo vemos como el downcasting si est permitido. Explico el ejemplo.
La clase Object es la clase de la que derivan todas las clases en Java, es la primera clase.
La clase String es una clase derivada de Object que contiene cadenas de texto.
Como la referencia o es una cadena de texto, cuando hacemos downcasting de Object a String,
el compilador ve que la referencia es una cadena de texto, el mismo tipo que hace referencia
o, y no da error. Esto compila sin problemas.

Aunque es raro usar esto de esta manera, nunca est de ms saber que existe y como
funciona.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 60
6.4 Implementando una interfaz
Al crear interfaces te aseguras que otro programador seguir las reglas que tu creaste para el
comportamiento de una clase.
Por ejemplo, si creas una interfaz como Volador te aseguras que alguien que cree un objeto
que vuele tenga los mtodos que necesitas para poder hacer que ese objeto vuele.

En el ejemplo vemos la implantacin forzosa de los mtodos que nos supone usar la interfaz
Volador.
Los comentarios los aade automticamente Eclipse al aceptar implementar los mtodos de la
interfaz. @Override significa sobrescribir, y eso es lo que tenemos que hacer, crear cdigo para
que esta clase pueda volar. Esos mtodos sern invocados desde otras clases que ya presumen
que todos los objetos que vuelan podrn realizar las acciones que indica la interfaz.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 61
Aunque el compilador no se va a quejar de que no pongas nada en los mtodos que
implementas, no quiere decir que ests haciendo una buena implementacin, por eso hay que
seguir esta serie de reglas:
Proveer de implementaciones no abstractas de todos los mtodos de la interfaz.
Usar las reglas de la sobrescritura, es decir, debe devolver el mismo tipo.
Declarar las excepciones no declaradas en los mtodos implantados que son
declarados en el mtodo de la interfaz o subclase. Veremos cmo se hace esto ms
adelante.
Mantener el nombre del mtodo de la interfaz y el mismo tipo o subtipo.
Una implementacin tambin puede ser abstracta por si misma, es decir, una interfaz puede
heredar otra interfaz, o ms de una, y no tiene que declarar los mtodos.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 62
Mientras que una clase slo puede heredar una clase, una interfaz puede heredar mltiples
clases.
Pero una interfaz no puede implementar nada aunque una clase puede implementar mltiples
clases.

Las interfaces son siempre pblicas, aunque no lo declares explcitamente.
Los mtodos implementados de la interfaz, han de ser pblicos, no puedes usar los
modificadores private, final, protected, o default.
Recuerda, que extends se usa para heredar otra clase, e implements se usa para clases
abstractas o interfaces. Las clases abstractas tienen mtodos no implementados (sin cuerpo) y
deben ser sobrescritos.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 63
6.5 Tipos de retornos en constructores sobrecargados
Sobrecargar un mtodo es crear otro mtodo con el mismo nombre pero aceptando diferentes
parmetros.

Tambin se puede sobrecargar un mtodo cuando una clase hereda a otra (heredando sus
mtodos) y rescribes el mtodo.

Cuando se crean mtodos que devuelven tipos distintos, segn los parmetros dados en el
mtodo, el tipo de retorno es distinto.

Lo que no puedes hacer es rescribir el mtodo en lugar de sobrecargarlo, as sin ms:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 64
Si quieres rescribir el mtodo en tu subclase, es decir, sobrescritura, puedes cambiar el tipo de
retorno si el tipo es un subtipo de la superclase.

En este ejemplo int y byte son distintos tipos, pero pueden ser casteados, es decir, si el valor
de int no supera el valor de 255 que es el rango mximo de byte, puede funcionar sin errores
en tiempo de ejecucin.
Otro ejemplo:

Aqu Main hereda Uno, as que Main automticamente es subtipo de Uno, por eso el retorno
del tipo es correcto.

6.5.1 Devolviendo un valor
Hay cinco sencillas reglas para devolver un valor.
1. Puedes devolver null en un mtodo con un objeto de referencia de tipo return.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 65
2. Puedes devolver un array. Aunque no hemos visto como se construye un array, en
el ejemplo se puede observar que se incluye unos corchetes [] al lado del tipo de
devolucin, para indicar que se trata de un array, y dentro del mtodo, al inicializar
la variable con los valores.


3. En un mtodo con tipo de retorno primitivo, puedes devolver cualquier valor o
variable que pueda ser convertida implcitamente al tipo declarado. Esto es lo que
vimos antes del casting.


4. Si el mtodo usa void (vaco) se presume que no devuelve nada, o sea, un valor
vaco. Hacer que devuelva un valor es ilegal:


5. Un mtodo que use un objeto de referencia, puede devolver cualquier tipo que
pueda ser casteado implcitamente al tipo de retorno.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 66
6.6 Autoboxing
Esta caracterstica consiste en convertir tipos automticamente, y es una caracterstica
aadida en Java 5.
Antes de existir esto, era ms complicado hacer una conversin evidente:

y ahora:

Donde se puede hacer autoboxing?
La regla general es que el boxing y unboxing funcionan cuando normalmente usas un dato
primitivo o un envoltorio (o sea, el nombre del objeto como Integer).





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 67
7.1 Construccin, reglas y sobrecargas de constructores

Cuando instancias un objeto con new se invoca el constructor de la clase siempre, pero
adems de esto, se ejecuta el constructor de la superclase, es decir, se ejecutan todos los
constructores de su superclase, y la ltima clase, de donde nacen todas las clases es Object.
Un constructor por defecto es como esto:

Lleva el mismo nombre de la clase y entre llaves no hay nada. Este constructor no es necesario
crearlo, el compilador lo hace por ti.
Los constructores normalmente se usan para inicializar las variables de la instancia, es decir,
los valores de las variables de la clase instanciada:

La palabra clave this se usa para hacer hincapi en que nos referirnos a la variable de instancia,
no a las variables del mtodo que tienen el mismo nombre. Adems, Eclipse pinta de azul las
variables de la instancia siempre que entienda que te refieres a ellas.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 68
Cuando creas un constructor, el constructor por defecto se omite, as que si quieres crear un
Circulo sin pasar los parmetros que has establecido, dar error:

Las opciones que muestra Eclipse para arreglar el error es:
Aadir los argumentos que encajen con Circulo(int, int, int)
Cambiar el constructor Circulo(int, int, int): Quitar los parmetros int, int, int
Crear el constructor Circulo()
Como ves, si uno de los consejos es crear el constructor que debera estar por defecto, es que
ya no est ah.
Aunque sea deseable siempre tener un constructor sin argumentos para una clase, muchas
veces, como en el ejemplo, no tiene sentido u ocasionara un error.
Puedes crear tantos constructores como quieras dentro de una clase.
Las reglas para crear un constructor:
Los constructores pueden usar cualquier modificador de acceso.
El nombre del constructor tiene que ser el mismo que el de la clase.
Los constructores no devuelven nada (no tienen return).
Es legal aunque estpido tener un mtodo con el mismo nombre que la clase. Esto no
significa que sea un constructor.
Si no se crea un constructor, el compilador crea uno por defecto, aunque no se vea en
el cdigo.
El constructor por defecto nunca lleva argumentos.
Si has escrito un constructor y quieres otro sin argumentos, tendrs que hacerlo t
mismo.
Cada constructor invoca implcitamente a this o super.
Si no incluyes this o super, el compilador lo har por ti, con o sin argumentos.
No se puede invocar a ninguna parte de una instancia hasta que su constructor se haya
ejecutado.
Solo las variables estticas y mtodos pueden ser accedidas con super o this.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 69
Las clases abstractas tambin tienen constructores, son ejecutados cuando la subclase
que los instancia son ejecutadas.
Las interfaces no tienen constructores, como no son parte de ningn objeto, no
forman parte de ningn rbol de herencia.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 70
7.2 Encadenamiento de constructores
Los constructores solo se ejecutan cuando usamos new en alguna clase, pero no slo se
ejecuta este nico constructor.
Al iniciar un constructor, tambin se inicia el de su superclase, hay un comando que se usa
implcitamente, se ejecuta super(), y sirve para invocar a la superclase, y as sucesivamente
hasta llegar a la superclase de todas las clases, Object.
Para ver el efecto domin, miremos este ejemplo:

La clase Main crea una instancia de la Clase4, pero fjate que antes de ejecutarse el
constructor de la clase 4, se ejecuta primero el de la superclase ms alta hasta llegar a la clase
4.
Cuando se ejecuta un mtodo sin usar super, en este ejemplo, info, se ejecuta el de la clase
que sobrescribe al de la superclase:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 71
Pero si quitamos el mtodo de la clase 4, se ejecuta el de la clase 1, lo mismo que si
hubiramos usado super(), solo que el compilador ya lo hace por nosotros:

Aqu inserto super() en la clase 4:

En este ejemplo, se usa super para invocar al constructor de la superclase, pero si te fijas, al
pasarle solo un argumento, se ejecuta el constructor de la clase2 sin arrojar error:

Al pasar 2 argumentos da error, porque no hay constructores con dos argumentos:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 72
Finalmente, si instanciamos la clase 1, la clase 2 podr leer las variables de la superclase:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 73
8.1 Mtodos y variables estticas
Hay que hacer una distincin entre las variables y variables marcadas como estticas.
Las variables no estticas se resetean en cada nueva clase instanciada, mientras que la variable
esttica pertenece a la clase, en lugar de a la instancia.
Estudiemos este ejemplo:

Mientras que numero ha sido declarado sin el modificador static, es inicializado en cada
instancia de la clase, mientras que conteo suma uno cada vez que se ejecuta el constructor, es
decir, cada vez que se usa new. En ambas clases instanciadas, conteo tiene el mismo valor, ya
que es esttico, no es una variable de la instancia, sino que es una variable esttica, que
pertenece a la clase, no a sus copias. Esto tambin es aplicable a los mtodos estticos.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 74
8.2 Accediendo a mtodos y variables estticas
En el momento en que no necesitas una instancia para acceder a los mtodos o variables
estticas usaremos el operador punto(.).
Reglas que debes conocer:

Adems los mtodos estticos no pueden ser rescritos.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 75
9.1 Funcionamiento del recolector de basuras
Vamos a ver lo que queremos decir cuando hablamos del recogedor de basuras en la tierra de
Java. A diez mil metros de altura, el recolector de basuras es la frase que se usa para describir
el manejo de memoria en Java. Cuando un programa se ejecuta (en Java, C, C++, Lisp, Ruby...)
usa la memoria de diferentes maneras. No vamos a meternos en la ciencia 101 de la
computacin, pero lo tpico de la memoria es que se use para crear una pila en el Heap, que es
la piscina donde Java pone sus mtodos y sus constantes. El Heap es la parte de la memoria
donde los objetos de Java viven, y es una y nica parte de memoria que esta de cualquier
modo envuelta en el proceso del recolector de basuras.
As, que la directiva del recolector de basuras es liberar al Heap, para dejar libre el mayor
espacio de memoria disponible. Lo que hace es borrar los objetos que no son alcanzables por
el programa Java que est corriendo. Hablaremos ms cuando lleguemos al siguiente punto.
Cuando el recolector de memoria se ejecuta, su propsito es encontrar y borrar objetos que
no pueden ser alcanzados. Imagina un programa Java que es el comienzo de un bucle de
creacin de objetos (que estn en el Heap), y que elimina los objetos cuando no se necesiten
ms, crear nuevos objetos, descartarlos, etc... la pieza que falta es el recolector de basuras.
Cuando se ejecuta, buscara esos objetos descartados y los borrara de la memoria
descargndola para que pueda continuar. Ah, el gran circulo de la vida.

9.1.1 Cuando se ejecuta el recolector de basuras?
El recolector de basuras funciona bajo el control de la JVM. La JVM decide cuando se ejecuta el
recolector de basuras. Dentro de tu programa Java puedes pedir a la JVM que ejecute el
recolector de basuras, pero no hay garantas, bajo ninguna circunstancia, de lo que la JVM va a
hacer. La JVM ejecutar el recolector cuando la memoria alcance mnimos. La experiencia me
indica que cuando le pides a la JVM que ejecute el recolector, la JVM garantiza que ser
ejecutado en corto plazo y justo cuando crees que puedes contar con ello, JVM omite tu
peticin

9.1.2 Cmo funciona el recolector de basuras?
No puedes estar seguro. Habrs podido escuchar que el recolector de basuras funciona con un
algoritmo de barrido, y para cualquier implementacin de Java puede ser cierto, pero la
especificacin de Java no garantiza ninguna implementacin en particular. Podras haber odo
que el recolector de basuras usa un conteo de referencia, una vez quizs si, quizs no. El
concepto ms importante de es:
Cuando el objeto es elegido para ser anulado por el recolector de basuras?
Para contestar a esta pregunta, tenemos que dar un salto hacia delante y hablar de hilos. En
un programa de Java, cada programa tiene desde uno a varios hilos. Cada hilo tiene su propia
pequea pila de ejecucin. Normalmente, tu (el programador) crea al menos un hilo para




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 76
ejecutar el programa, el primero con el mtodo main() en el fondo de la pila. Sin embargo,
como aprenders en detalle ms adelante, hay muchas razones para lanzar hilos de ejecucin
adicionales desde tu hilo principal. Aparte de tener su propia pila de ejecucin, cada hilo tiene
su ciclo de vida. Por ahora, todo lo que necesitamos saber es que los hilos pueden estar vivos o
muertos. Con esta informacin, podemos decir con contundente claridad que un objeto es
elegido para el recolector de basuras cuando no hay hilos vivos accediendo a el.
Basndonos en esta definicin, el recolector de basuras hace algo de magia, operaciones
desconocidas, y cuando descubre un objeto que no puede ser alcanzado por un hilo vivo,
considera que el objeto es elegible para ser eliminado, puede llegar incluso a borrarlo en el
mismo momento. (Si, lo adivinaste, puede ocurrir que tampoco lo llegue a borrar nunca).
Cuando hablamos sobre el alcance de un objeto, estamos hablando realmente sobre tener una
variable de referencia alcanzable que se refiera al objeto en cuestin. Si nuestro programa Java
tiene una variable de referencia que hace referencia al objeto, y esa variable de referencia est
disponible en un hilo vivo, entonces ese objeto se le considera alcanzable. Hablaremos ms
sobre como los objetos puede convertirse en inalcanzables en la siguiente seccin.
9.1.3 Puede una aplicacin Java quedarse sin memoria?
S. El recolector de basuras intenta borrar todos los objetos de la memoria cuando no se usan.
Sin embargo, si mantienes muchos objetos vivos a la vez (objetos referenciados por otros
objetos) el sistema puede llegar a quedarse sin memoria. El recolector de basuras no puede
asegurar que haya suficiente memoria, solo que la memoria disponible ser manejada de la
forma ms eficiente posible.

9.2 Escribir cdigo que maneje explcitamente objetos elegibles para ser borrados
En esta seccin vamos a mostrar cmo hacer objetos elegibles para el recolector de basuras
usando el cdigo actual. Tambin vamos a discutir cmo forzar al recolector de basuras si es
necesario, y como podemos ejecutar una limpieza adicional en objetos antes de que sean
borrados de la memoria.
Una referencia nula
Como hemos visto antes, un objeto se convierte en apto para ser borrado cuando no hay
referencias que lo apunten. Obviamente, sino hay referencias, no importa lo que le ocurra al
objeto. Para nuestro propsito es solo algo flotando en el espacio, sin usar, inaccesible y que
ha dejado de necesitarse.
La primera manera de borrar una referencia a un objeto es seleccionar la variable de
referencia que apunta al objeto y volverlo null. Examina el siguiente cdigo:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 77

El StringBuffer con el valor "hello" se le asigna la variable sb en la tercera linea. Para hacer este
objeto apto para el GC (Garbage Collector, recolector de basuras), le asignamos a sb el valor de
null, lo que elimina la nica referencia que exista al objeto StringBuffer.
Una vez que la lnea 6 se ejecuta, nuestro pequeo "hello" est condenado para el GC.

9.3 Reasignado una variable de referencia
Tambin podemos desemparejar una variable de referencia de un objeto asignndole a la
referencia, otro objeto. Examina este cdigo:

Los objetos creados en un mtodo tambin necesitan ser considerados. Cuando un mtodo se
invoca, ninguna variable local existe ms all de la duracin del mtodo. Una vez el mtodo ha
terminado, el objeto creado en el mtodo es apto para el GC.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 78
Hay una excepcin obvia. Si se devuelve un objeto del mtodo, su referencia puede ser
asignada a una variable de referencia en el mtodo que lo llam, as que, no ser apto para la
coleccin. Examina este cdigo:

En el cdigo hemos creado un mtodo llamado getDate() que devuelve un objeto Date. Este
mtodo crea dos objetos: un Date y un StringBuffer que contiene la informacin. En el
momento que el mtodo devuelve el objeto Date, no ser apto para la GC aunque el mtodo
se haya completado. El StringBuffer ser apto, aunque no lo hayamos hecho explcitamente, la
variable ahora tiene asignado un null.

9.4 Aislando una referencia
Hay otra manera en la que los objetos se conviertan en aptos para la GC, aunque tengan unas
referencias vlidas. Nosotros llamamos a este escenario "isla de la soledad".
Un ejemplo simple es que una clase que tiene una variable de instancia que es variable de
referencia a otra instancia de la misma clase. Ahora imagnate que las dos instancias de la
misma clase existen y que la una y la otra estn apuntndose. Si las otras referencias a estos
objetos son eliminadas, entonces incluso aunque estas referencias sean vlidas, no hay hilo
que acceda a estas variables de referencia. Cuando el GC se ejecuta, puede normalmente,
encontrar estas islas y eliminarlas. Como te puedes imaginar, estas islas pueden llegar a ser
bastante grandes, tericamente contiene cientos de objetos.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 79
Examina el siguiente cdigo:

Cuando el cdigo alcanza //, las tres islas previamente conocidas como i2, i3 e i4, tienen
variables de instancias que apuntan las unas a las otras, pero sus enlaces hacia el mundo, ha
sido anuladas. Estos tres objetos son aptos para la GC. Esto cubre todo lo que necesitaras
saber sobre crear objetos aptos para la GC.

9.5 Forzando el recolector de basuras
La primera cosa que debera de mencionarse aqu es eso, contrariamente al ttulo de esta
seccin, el GC no puede ser forzado. Sin embargo, Java provee de mtodos que te permiten
solicitar que la JVM efectu la ejecucin del GC. Por ejemplo, si estas a punto de ejecutar
algunas operaciones sensibles, probablemente querrs minimizar el riesgo de lag causado por
el recolector de basuras. Pero tienes que recordar que los mtodos que Java provee son
peticiones, no demandas, la JVM har lo mejor respecto a lo que solicitas, pero no hay
garantas de que efectuar la peticin.
En realidad, solo es posible sugerir a la JVM que ejecute el GC. Sin embargo tampoco hay
garantas de que elimine todos los objetos sin usar de la memoria (aunque el GC se ejecute). Es
esencial que entiendas ese concepto para el examen.
La rutina del GC que Java suministra son miembros de la clase Runtime. Esta es una clase
especial que solo tiene un objeto (un Singleton) para cada programa. El objeto Runtime provee
de mecanismos para comunicar directamente con la mquina virtual. Para conseguir una
instancia de Runtime, puedes usar el mtodo Runtime.getRuntime(), que te devuelve el
Singleton. Una vez que lo tengas, puedes invocar al recolector de basuras usando el mtodo
gc(). Alternativamente, puedes invocar al mismo mtodo en la clase System, que es un
mtodo esttico que puede funcionar obteniendo el Singleton para ti. La manera ms simple
para pedirle al GC que se ejecute es:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 80
Tericamente, despus de llamarlo, tendrs mucha memoria libre. Decimos tericamente
porque esta rutina no funciona siempre de esa manera. Primero, tu JVM no puede tener
implementada esta rutina; la especificacin del lenguaje no permite hacer nada. Segundo, otro
hilo puede ganar un montn de memoria en el momento que se ejecute el GC.
Esto no es decir que System.gc() es un mtodo intil, es mucho mejor que nada. Simplemente
no puedes confiar en System.gc() para liberar suficiente memoria, as que no tienes que
preocuparte sobre quedarte sin memoria.
Ahora que de alguna manera nos hemos familiarizado con cmo funciona, hagamos un
pequeo experimento para ver si podemos ver los efectos del GC. El siguiente programa nos
permitir saber cunta memoria tiene disponible la JVM y cuanta ha libreado. Esto va a crear
10.000 objetos Date. Despus, le dir cuanta memoria queda, llamar al GC (el cual decidir si
se va a ejecutar, el programa se detendr hasta que todos los objetos sean eliminados). La
memoria final debera indicarse cuando se haya ejecutado. Veamos el programa:

Ahora veamos el resultado:

Como puede verse, la JVM ha decidido recolectar la basura de los objetos aptos para ser
eliminados. En el ejemplo, le sugerimos a la JVM que ejecutase el GC con 458Kb de memoria
restante, y nos honr con su aparicin. Este programa solo tiene un hilo corriendo, as que no
haba nada ms funcionando cuando fue ejecutado. Ten en mente que el comportamiento de
gc() cuando es ejecutado puede ser diferente, as que no hay garanta que los objetos sin uso




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 81
sean eliminados de la memoria. La nica cosa que se garantiza es que el GC funcionara antes
de arrojar una excepcin OutOfMemoryException.

9.6 Limpiar antes de ejecutar el GC - el mtodo finalize()
Java provee de un mecanismo para ejecutar un cdigo justo despus de que tu objeto sea
borrado por el GC. Este cdigo est en un mtodo llamado finalize() que todas las clases
heredan de Object. Sobre el tapete suena como una gran idea, quizs tu objeto consuma algo
ms de recursos, y te gustara cerrarlo antes de que sea borrado. El problema es ese, que no
puedes contar con el GC siempre para borrar un objeto. As, que cualquier cdigo que pongas
dentro de tu clase, el mtodo finalize() tampoco te garantiza que se vaya a ejecutar, as que
tampoco es recomendable que pongas cdigo esencial dentro de este mtodo. El caso, es que
recomendamos que no sobrescribas el mtodo finalize().
Un pequeo truco para finalize()
Hay un par de conceptos concernientes a este mtodo que necesitaras recordar:
Para cualquier objeto dado, el mtodo ser llamado una vez por el GC.
Llamar a este mtodo puede acabar en que el objeto sea salvado del borrado.
Miraremos estos estamentos ms adelante.
Lo primero de todo, recordar que el cdigo que pongas dentro de un mtodo normal, puedes
ponerlo en finalize(). Por ejemplo, en el mtodo finalize() podras escribir el cdigo que pasa
una referencia a un objeto en cuestin hacia otro objeto, efectivamente, el objeto acaba en el
GC. Si en el mismo punto, ms tarde en este mismo objeto se convierte en apto para el GC, el
GC puede pausar este proceso y borrarlo. El GC sin embargo recordar, que en este objeto,
finalize() ya se estaba ejecutando, y no va a ser ejecutado otra vez.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 82
10. Operadores
Si tienes variables, tendrs que modificarlas. Necesitars incrementarlas, sumarlas,
compararlas (hay como una docena de formas). En este captulo, aprenders como se hace
todo eso en Java.
Los operadores de Java producen nuevos valores desde uno o ms operandos (solo queremos
dejarlo todo claro, recuerdo que los operadores son las cosas a la izquierda y derecha del
operador). El resultado de la mayora de las operaciones son un valor booleano o numrico. Ya
que sabes que Java no es C++, no vas a sorprenderte de que los operadores de Java no son
sobrecargados. Sin embargo existen unas pocas excepciones donde los operadores pueden
venir sobrecargados.
El operador + puede ser usado para aadir dos nmeros o para hacer una
concatenacin si el operando es una cadena.
Los operadores &, |, y ^ pueden ser usados de dos formas distintas, aunque en esta
versin del examen, sus capacidades de bit no sern testadas.

10.1 Operadores de asignacin
Cuando asignamos un valor a un primitivo, el tamao importa. Pero asegrate de saber
cundo hay un casteo implcito, cuando es el casteo explcito necesario y cuando puede ocurrir
la truncacin (por ejemplo, acurdate de que un int puede entrar en un byte siempre que no
supere el rango).
Recuerda que una variable de referencia no es un objeto, es una manera de conseguir un
objeto. (Sabemos que todos los programadores de C++ se mueren por decirnos que eso es un
puntero, pero nosotros no.)
Cuando asignamos un valor a una variable de referencia, el tipo importa. Recuerda las reglas
para los supertipos, subtipos y arrays.
Ahora cubriremos unos pocos de detalles de los operadores de y ms adelante, miraremos
cmo funciona el asignador = con las cadenas (las cuales, son inmutables).

10.2 Operadores de asignacin compuestos
Actualmente hay 11 asignadores, pero solo cuatro son los ms usados (+=, -=,*= y /=) en el
examen (depende del objetivo). Los operadores de asignacin compuestos son la manera ms
fcil de ahorrar unos pocos golpes de teclado. Aqu hay varios ejemplos de asignaciones,
primero, sin usar el operador de compuesto,





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 83
Ahora con los operadores compuestos:

Por supuesto, los resultados sern los mismos.

10.3 Operadores relacionales
Hay seis operadores relacionales (<, <=, >, >=, == y !=). Los operadores relacionales siempre
dan como resultado un booleano (true o false). Este valor booleano es usado a menudo como
sigue:

pero el valor resultante puede ser tambin asignado directamente de booleano a primitivo:

Java tiene cuatro operadores relacionales que pueden ser usados para usarse en la
comparacin de cualquier combinacin de enteros, decimales o caracteres:
> mayor que
>= mayor o igual que
< menor que
<= menor o igual que
Observemos algunas comparaciones validas:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 84
En el cdigo anterior, usamos una comparacin entre caracteres. Tambin es legal comparar
un carcter primitivo con un nmero (aunque no sea un gran estilo de programacin). Al
ejecutar el cdigo, tendremos la siguiente salida:
The animal is a gray elephant

Hemos mencionado que los caracteres pueden ser usados en operadores de comparacin.
Cuando comparamos un carcter con otro carcter, o un carcter con un nmero, Java usara el
valor Unicode del valor del carcter como valor numrico para la comparacin.

10.4 Operaciones de igualdad
Java tiene dos operadores de igualdad (tambin llamados operadores relacionales) que
comparan dos cosas similares y devuelve un valor booleano que representa true o false de las
cosas que se estn comparando. Estos operadores son:
== igual (mejor conocido como igual que)
!= no igual (mejor conocido como no igual que)
Cada comparador individual puede involucrar dos nmeros (incluyendo los caracteres), dos
valores booleanos, o dos variables de referencia a objetos. En todo caso, no puedes comparar
tipos incompatibles. Cual sera una respuesta si preguntamos si un booleano es igual que un
carcter? o si un botn es lo mismo que una cadena de texto? (Exactamente, tonteras, porque
no tienen sentido). Hay cuatro tipos diferentes de cosas que pueden ser comparadas:
nmeros
caracteres
booleanos primitivos
variables de referencia a objetos
As que, que compara == (son dos signos de =)? El valor en la variable, en otras palabras, el
patrn de bits.

10.5 Comparacin de primitivos
La mayora de programadores estn familiarizados con la comparacin de valores primitivos. El
siguiente cdigo muestra algunos test de igualdad sobre variables:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 85

El programa mostrara:
character 'a' == 'a'? true
character 'a' == 'b'? false
5 != 6? true
5.0 == 5L? true
true == false? false
Como puedes ver, normalmente si un numero decimal es comparado con un entero y el valor
es el mismo, el operador == (dos signos de igualdad =) devuelve true, tal como se esperaba.

10.6 Igualdad para variables de referencia
Tal como vimos antes, las dos variables de referencia pueden referirse al mismo objeto, tal
como demuestra este cdigo:

Despus de ejecutar este cdigo, ambas variables estn apuntando al mismo objeto. Las
variables de referencia pueden ser comprobadas para ver si son el mismo objeto usando el
operador igual que(==). Recuerda que este operador examina los bits contenidos en la
variable, as que para las variables de referencia significa que si ambas referencias contenidas
son iguales, entonces se refieren al mismo objeto.
Examina el siguiente cdigo:

Este objeto crea tres variables de referencia. Las primeras dos son dos objetos JButton
distintos, mientras que a la tercera se le asigna la primera referencia. Cuando este programa se
ejecuta, se muestra el siguiente resultado:
Is reference a == b? false
Is reference a == c? true
Esto nos muestra que la primera y tercera referencia son la misma instancia de JButton. El
operador "igual que" no har la comparacin si los objetos son significativamente




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 86
equivalentes, un concepto que cubriremos con las colecciones, cuando veamos el
mtodo equals() (lo opuesto a lo que estamos viendo aqu).

10.7 Igualdad para enumeraciones
Una vez que has declarado una enumeracin, no se puede expandir. En tiempo de ejecucin
no hay manera de aadir nuevas constantes. Naturalmente, puedes tener tantas variables
como quieras, as que es importante el poder comparar dos variables de referencia de
enumeracin para ver si son iguales, por ejemplo, para ver si se refieren a la misma constante
de enumeracin. Tambin puedes usar el operador == o el mtodo equals() para determinar si
las dos variables se estn refiriendo a la misma constante de enumeracin:

Sabemos que }} es bastante feo de ver, pero te estoy preparando. Esto da como salida:
==
dot equals


10.8 Comparacin con instanceof()
Este mtodo se usa solo para las variables de referencia, y puedes usarlo para saber si un
objeto es de un tipo particular. Por tipo, queremos decir la clase o la interface, en otras
palabras, si el objeto referido por la variable de la izquierda pasa el test de ES-UN para el tipo
de clase o interface de la derecha

esto imprime:
s is a String

Incluso si el objeto que est siendo testeado no es una instancia del tipo de la clase del lado de
la derecha del operador, instanceof devolver true si el objeto es compatible con el operando
de la derecha.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 87
El siguiente ejemplo demuestra el uso normal de instanceof, verificar si un objeto es instancia
de uno de sus subtipos antes de intentar hacer un downcasting:

El cdigo anterior compila y muestra:
'a' refers to a B
En el ejemplo, usamos instanceof para proteger al programa de un downcasting ilegal. Puedes
testear un objeto de referencia con su propia clase, o cualquiera de sus subclases. Esto
significa que cualquier objeto de referencia ser evaluado a true si usas instanceof con el
tipo Object, tal como sigue:

lo cual imprime:
b is definitely an Object

Hay que aadir, que un valor null es tambin valido en una referencia. Esto siempre dar false:



Esto imprime: false false





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 88
10.8.1 Errores de compilacin con instanceof

No puedes usar instanceof en dos tipos de jerarquas distintas. Por ejemplo, esto no compilara:



La compilacin falla, no hay manera de que d pueda referirse a Cat o a algn subtipo de Cat.
El siguiente resumen muestra el uso de instanceof en el siguiente cdigo:







10.9 Operadores aritmticos

Estoy seguro de que estas familiarizado con los operadores aritmticos.
+ sumar
- restar
* multiplicacin
/ divisin
Se pueden usar de manera estndar:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 89
10.9.1 El operador resto %
Este operador puede que no te sea familiar. Lo que hace es obtener el resultado de dividir los
operandos, tal como demuestra este cdigo:



Al ejecutar el cdigo, imprime:

The result of 15 % 4 is the remainder of 15 divided by 4. The
remainder is 3
Recuerda: Las expresiones son evaluadas de izquierda a derecha por defecto, Puedes cambiar
esta secuencia aadiendo parntesis. Tambin recuerda que *,/ y % preceden sobre + y -.

10.9.2 Operador de concatenacin de cadenas
El signo ms puede ser usado para concatenar dos cadenas de caracteres.



La concatenacin se pone interesante cuando combinas cadenas y nmeros:



Que har el operador +? sumar las variables numricas o concatenara los caracteres? Ok, ya
has tenido tiempo de pensarlo. Los valores int sern tratados como caracteres y puestos a la
derecha de la cadena, dando de resultado:

String37

As que el cdigo se lee como "empieza con cadena, luego cadena "3" y cadena "7".
Sin embargo, si usas los parntesis alrededor de las variables numricas tal como se muestra:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 90
tendremos: String10
Al usar los parntesis haces que se evale primero lo que est entre ellos, as que el operador
ms a la derecha lo que hace es aadir el resultado del parntesis. Recuerda esta regla:
Si el operador es una cadena, el operador ms se convierta en un concatenador de cadenas. Si
ambos operadores son nmeros, el operador + hace una suma.
Alguna vez encontraras problemas al decidir si el operador de la izquierda es cadena o no. En
el examen no lo esperes tan obvio. Observa el siguiente cdigo:

No puedes saber que el operador + se est usando para sumar o concatenar hasta averiguar el
tipo de devolucin de foo. Finalmente tienes que saber que es vlido usar el operador += con
cadenas:


Como el operador += para hacer una suma, pues el resultado es 1234567.



10.10 Operadores de incremento y decremento

Java tiene dos operadores que incrementan o decrementan una variable en 1. Estos
operadores estn compuestos de dos signos mas o dos menos (++ --). El operador se sita
despus del operando, o despus para cambiar su valor. Sin embargo, cuando el operador est
a un lado u otro, el resultado cambia, veamos este ejemplo:

Observa la 4a lnea del programa donde el operador de incremento esta despus de la
variable player. Esto significa que estamos incrementando el valor en 1 pero justamente antes
de arrojar el valor en la pantalla. Cuando ejecutamos el programa, aparece esto:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 91
%java MathTest
players online: 0
The value of players is 1
The value of players is now 2

Tienes que advertir que la variable escrita en la pantalla, primero dice el valor, y luego efecta
la operacin de incremento si el operador esta despus de la variable.
La lnea 5 no incrementa la variable, solo est haciendo una concatenacin.
La lnea 6 incrementa el valor de la variable antes de ser mostrada en pantalla.
Puedes esperar un remix de operadores tal como este ejemplo:


El cdigo imprime: x = 3 y = 4

Esto se lee como "Si 3 es igual a 2 O 3 < 4".

La primera expresin compara x e y, y el resultado es false, porque el incremento de x no
sucede hasta que el test == est hecho. Lo siguiente que ocurre es que se incrementa x, as que
ahora x vale 3. Luego el segundo checkeo dice que x es menor que y, pero ya hemos
incrementado y antes en la comparacin con x, as que la comparacin (3 < 4) es cierta y se
muestra el resultado.


10.11 Operador condicional

El operador condicional es un operador ternario (tiene tres operandos) y se usa para evaluar
una expresin booleana, se parece mucho a if, solo que en lugar de ejecutar un bloque lo que
hace es asignarle un valor a la variable. Su construccin es como sigue:



Puedes leer que el nmero de pets es 3. Los siguiente que hacemos es asignar el estatus a la
variable. Si el nmero de pets es menor que 4, le asigna un mensaje, de otra manera, le asigna
el otro.

El operador condicional comienza por una operacin booleana seguida de dos posibles valores
a la izquierda del operador =. El primero valor (el de la izquierda del :) se asigna si la condicin
se cumple, y el segundo valor se asigna si la condicin no se cumple. Puedes incluso anidar
operadores condicionales en un solo estamento:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 92




10.12 Operadores lgicos

Hay seis operadores lgicos (&, |,^, !, &&, ||). En alguna documentacin de Sun se usa otra
terminologa para estos operadores, pero nuestro propsito son los seis de arriba.



10.13 Operadores e Bitwise

Okey, esto puede ser confuso. De los seis operadores lgicos listados arriba, tres de ellos
(&, |,^) pueden ser usados tambin como operadores bitwise. Los operadores de bitwise
fueron incluidos en versiones anteriores del examen, pero no estn en el examen de Java 5.
Aqu hay varios estamentos que usan operadores de bitwise:



Los operadores de bit comparan dos variables bit a bit, y devuelve una variable cuyos bits han
sido basados en cualquier de las dos variables y siendo comparados sus bits con AND (&), otro
con OR(|) y otro con ON(^), la consola muestra:

0 15 1



10.14 Atajo para operadores lgicos
Hay cinco operadores lgicos que son usados para evaluar estamentos que contienen ms de una
expresin booleana. La mayora de los ms usados tienen dos atajos sintcticos, son AND, y
OR. Se representan:
&& AND
|| OR




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 93
Para que la condicin AND se cumpla, tiene que ser todo cierto, mientras que con OR es cierto
si cualquiera de las comparaciones es verdadera. Estos atajos se evalan desde la izquierda a la
derecha, si alguna condicin no se cumple, no se sigue evaluando el estamento.
class Logical {
public static void main(String [] args) {
boolean b = true && false;
System.out.println("boolean b = " + b);
}
}
esto no muestra

%java Logical
boolean b = false


Presta atencin al siguiente ejemplo:


da como resultado

% java TestOR
i < 5
Result is true
i >= 5
i >= 5







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 94
Aqu esta lo que ha pasado en el mtodo main():
1. Cuando llegamos a la lnea 3, se evala el primer operando con ||
2. El mtodo isItSmall(3) se invoca e imprime "i < 5" y devuelve true
3. El operando de la lnea 3 es cierto, el operador || no evala la siguiente comparacin
as que nunca vemos "i >= 5" que se hubiera mostrado si se hubiera ejecutado el
segundo estamento.
4. Se evala la lnea 6, comenzando con el primer operando ||
5. El mtodo isItSmall(6) se invoca imprimiendo "i >= 5" y devolviendo false.
6. Como el primer operador || de la lnea 6 es false, el operador || no puede saltar el
segundo operando, porque todava hay una expresin que puede ser verdad, si se
evala el segundo operador dar true.
7. Se invoca isItSmall(9) que imprime "i >= 5".
8. El mtodo isItSmall(9) devuelve false as que la expresin de la lnea 6 es falsa, por lo
que la lnea 7 nunca se ejecuta.

10.15 Operadores lgicos sin atajos
Hay dos operadores lgicos, &, AND y | OR.
Estos operadores son usados en expresiones lgicas al igual que && y ||, pero no son atajos,
estos evalan ambos lados de la expresin siempre. Son ineficientes. Por ejemplo, si el primer
operando con expresin & es falso, el segundo operando tambin se evaluara, aunque el
resultado, evidentemente sea false. Y el OR tambin es ineficiente, si el primer operando es
true, JVM todava evaluara el segundo operador aun sabiendo que el resultado dar true.


10.16 Operadores lgicos ^ y !

Los ltimos operadores lgicos son: ^ XOR y ! booleano invertido.
El OR exclusivo (o XOR) slo evala valores booleanos. El operador ^ es tratado como un
operador sin atajo y siempre evala ambos operandos en una expresin. Para el XOR, la
expresin para que d true tiene que ser EXACTAMENTE que uno de los operandos sea true,
por ejemplo:


resulta: xor false

La expresin anterior devuelve false porque ambos operandos son verdaderos. El operador !
devuelve el valor contrario del booleano:



se puede leer como "si no es verdad que 7 == 5," y la salida produce




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 95
not equal
Aqu hay otro ejemplo de booleano:

da como resultado:
! true false
En el cdigo anterior tienes que fijarte en que el test & es aprobado (imprimiendo true) y que
el valor de la variable booleana f no cambi, as que imprimi false.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 96
11 Control de flujo, excepciones y aserciones
Como te imaginarias escribiendo un cdigo usando un lenguaje que no te permitiese ejecutar
estamentos de forma condicional? El control de flujo es la clave de la mayora de los lenguajes
de programacin, y Java ofrece varias maneras de hacerlo. Algo como if o el bucle for son
estamentos comunes en la mayora de los lenguajes. Pero Java tambin arroja un par de
controles que podras no haber usado antes, las excepciones y las aserciones.
El estamento if y switch son de tipo condicin/decisin que permite a tu programa tener
diferentes comportamientos dependiendo del resultado de un test lgico. Java provee de tres
constructores de bucle, for, while y do, as que puedes ejecutar el mismo cdigo una y otra vez
dependiendo de que se cumpla una condicin. Las excepciones dan una manera simple para
organizar el cdigo de forma sencilla que se ocupa de problemas que pudieran surgir durante
la ejecucin. Finalmente, la asercin, aadido en el lenguaje en el 1.4, te da una manera de
comprobar y debuguear en condiciones que tu esperas puedan fallar mientras desarrollas,
cuando no necesariamente necesites o quieras sobrecargar el manejo de excepciones.
Con estas herramientas, puedes construir un programa robusto que pueda manejar cualquier
situacin lgica con elegancia.

11.1 Estamento if
El if y el switch se refieren normalmente a estamentos de decisiones. Cuando usas un
estamento de decisin en tu programa, le estas pidiendo al programa que evale una
expresin dada para determinar qu accin coger. Vamos a ver el estamento if.
El formato bsico de un estamento if-else
La expresin entre parntesis debe evaluarse a booleano. Normalmente, se usa para evaluar
una expresin y ejecutar un bloque u otro segn si el resultado es verdadero o falso. El
siguiente cdigo demuestra un estamento if-else valido:


El bloque else es opcional, as que tambin puedes usar lo siguiente:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 97
El cdigo asignara un 2 si la evaluacin es true. Las siguientes lneas fuera de las llaves se
ejecutaran sin importar el resultado. Hasta las llaves son opcionales si solo quieres ejecutar un
nico estamento (el inmediato justo despus del cierre del parntesis):


Ten cuidado con el cdigo de arriba, porque puedes pensar que se lee as:

Si x es ms grande que 3, entonces poner y a 2, la z a z+8 y luego a =y + x.

Pero en realidad las dos ltimas lneas se ejecutarn, no son parte del bloque de condicin.

Podras tener la necesidad de anidar estamentos if-else (no es recomendado para la lectura).
Puedes inicializar un if-else para evaluar mltiples condiciones. Los siguientes ejemplos usan
dos condiciones, as que si el primer test falla, ejecutaremos un segundo test para decidir qu
hacer:



Esto podra rescribirse tal como:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 98
Hay un par de reglas para el uso de if-else-else if:
Puedes tener desde cero else hasta uno para cada if, y deben ir despus de cada if.
Una vez que else es ejecutado, ninguno de los dems else o if sern ejecutados.



11.2 Estamento switch

Una manera de simular el uso de switch es usar mltiples if. Echa un vistazo al cdigo if-else y
fjate como de confuso puede ser tener if anidados, incluso con pocos niveles:



y ahora lo mismo representado con switch:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 99
Por si an no has pillado la estructura de un switch, te lo explico brevemente.

Como cualquier bloque, un switch rodea entre llaves los cdigos.
Entre parntesis, switch, evala la variable.
En cada caso, case, ejecuta las instrucciones cuando el caso coincide, hasta llegar a break.
Si no se pusiese un break, se continuaran ejecutando las dems instrucciones contenidas en
los siguientes case. Es opcional.
Con default, te aseguras de ejecutar alguna instruccin si no se cumple ningn caso. Es
opcional.



11.2.1 Expresiones vlidas para switch y case

El uso general de switch es:



Una expresin switch debe evaluar un carcter, byte, short, int o como en Java 5, una
enumeracin. Eso significa que si no ests usando una enumeracin, solo puedes usar
variables y valores que puedan ser automticamente ascendidos (en otras palabras, casteados)
a int . No va a compilar si usas cualquier otra cosa, incluyendo nmeros long, float o double.

El estamento case evala un valor constante del mismo tipo expresado en switch, con algo
adicional, y gran, restriccin: la constante case debe ser una constante en tiempo de
ejecucin! Lo que significa que solo puedes usar variables constantes o finales. No es suficiente
con que sea una variable final, debe compilar como constante:



switch solo puede evaluar la igualdad. Quiere decir que los operadores como mayor que,
menor que, etc.. no se pueden usar en case. Lo siguiente es una expresin vlida usando un
mtodo de invocacin en el estamento switch. Fjate que en este cdigo, para que sea vlido,
el mtodo est siendo invocado en la referencia del objeto, debe devolver un valor compatible
con int.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 100


Qu pasa si usas una variable menor que un int en un switch? Observa el ejemplo:



El cdigo no compilar. Aunque el estamento es vlido, el byte es implcitamente casteado
a int, el segundo case (128) es demasiado grande para un byte (hasta 127 positivos) y el
compilador lo sabe! Intentar compilar la ltima instruccin da un error como este:



Tampoco no es vlido tener ms de un case usando el mismo valor. Por ejemplo el siguiente
bloque no compilara porque usa 2 case con el valor 80:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 101
Es lcito aprovechar la potencia del boxing en una expresin switch. Por ejemplo, esto es
vlido:





11.2.2 Interrupciones y flujo en los boques switch

Ya estamos preparados para discutir el estamento break, y mas detalles sobre control de flujo
en un switch. Lo ms importante a recordar es que la ejecucin de un switch funciona as:

Las constantes en case son evaluadas desde arriba, hacia abajo, y el primer valor evaluado en
case que coincida con la expresin switch , ser el punto de entrada para ejecutar el bloque
case.

En otras palabras, una vez que un case sea ejecutado, la JVM ejecutar los dems bloques
case siguientes, hasta encontrar un estamento break.

El siguiente ejemplo usa una enumeracin en un estamento case:



En este ejemplo, el case green: encaja, as que la JVM ejecutar ese bloque y los subsiguientes
produciendo la salida:

green blue done

De nuevo, cuando el programa encuentra la palabra break durante la ejecucin de un
estamento switch, la ejecucin del bloque case finalizara y saldr del bloque switch. Si se
omite break, el programa simplemente, ejecutar todos los bloques case hasta que termine el
estamento switch. Observa el siguiente cdigo:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 102


mostrar:

x is one
x is two
x is three
out of the switch

Esta combinacin sucede cuando el cdigo no encuentra el estamento break, la ejecucin se
mantiene hasta el final. Esta clase de ejecucin se la conoce como "fall-through" porque la
manera de ejecutarse cae desde el primer case ejecutado hasta el ltimo.
Recuerda, que el punto de entrada de ejecucin es el primer case que coincida con la
evaluacin de switch. En otras palabras, no puedes pensar "Encuentra la coincidencia, ejecuta
el bloque y sal". Porque eso no funciona as. Si t quieres que funcione as, tienes que
usar break en cada case como en el ejemplo:



Este cdigo mostrar:

x is one
out of the switch

y ya est. Hemos entrado dentro del bloque switch en el case 1. Porque encaja con la
evaluacin en switch, hemos conseguido ejecutar el estamento println, luego llega a break y
salta al final de switch. Un ejemplo interesante del uso de este fall through se muestra en el
siguiente cdigo:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 103


El estamento switch imprimir "x is an even number" o nada, dependiendo de si el numero
esta entre uno y 10 y es par o impar. Por ejemplo, si x vale 4, la ejecucin comenzara por
el case 4 hasta el final.

Nota: Debido a que el fall-through es menos intuitivo, Sun recomienda que aadas un
comentario // fall through cuando uses esta lgica.



11.2.3 El caso default

Qu pasa si en el cdigo anterior, tu queras imprimir "x is an odd number" si ninguno de los
casos (incluso los impares) encajaba? No podras ponerlo despus del estamento de switch, o
incluso en el ltimo case, porque en ambas situaciones, podra imprimir siempre. Para
conseguir este comportamiento necesitaras la palabra clave default. (Sin embargo, si t te has
preguntado por qu hay una palabra clave default aunque no lo usemos como modificador de
acceso, vers ahora que default se usa para un propsito completamente distinto). El nico
cambio que necesitamos hacer es aadir un caso por defecto en el cdigo:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 104
Los bucles de Java vienen en tres sabores: while, do y for (y a partir de Java 5, for tiene dos
variantes). Los tres te permiten repetir un bloque de cdigo tantas veces como se cumple la
condicin, o especificas veces de iteraciones. Probablemente estas familiarizado con los bucles
en otros lenguajes, as que si eres nuevo en Java, no ser ningn problema aprenderlos.



11.3 Estamento while

Este bucle es bueno en escenarios donde no sabes la cantidad de veces que un bloque de
estamentos tiene que repetirse, pero quieres continuar haciendo el bucle mientras la
condicin se cumpla. Un estamento while es como esto:







En este caso, como en todos los bucles, la expresin debe evaluarse como un resultado
booleano. El cuerpo del bucle se ejecutar mientras la expresin resulte true. Una vez dentro
del bucle, el cuerpo se repetir hasta que la condicin sea evaluada a false. En el ejemplo
anterior, el programa entrara en el bucle porque x es igual a 2. Sin embargo, x es incrementada
en el bucle, as que cuando la condicin se comprueba otra vez, la evaluacin da false y sale
del bucle.

Cualquier variable usada en la expresin while debe ser declarada antes de que la expresin
sea evaluada, en otras palabras, no puedes decir:



Nuevamente, por qu lo haras? En lugar de evaluar la variable, la declararas y la inicializaras,
as que siempre tendra el mismo valor. No se parece mucho a una evaluacin!
La clave est en recordar que el bucle while puede ni llegar a ejecutarse. Si la evaluacin
devuelve false, el cuerpo de while se ignorara.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 105


El cdigo devuelve:

past the loop

Ya que la expresin (x > 8) se evala falsa, nada en el interior del cuerpo se ejecuta.



11.4 Estamento do while

El uso de do while es similar a while excepto que la expresin no se evala hasta que el cdigo
dentro del bucle se ejecuta, as que se garantiza que el cdigo del bloque se ejecutar al
menos una vez. El siguiente ejemplo muestra un do-while en accin:



El System.out.println() imprimir una vez, aunque la expresin se evala falsa. Recuerda, el
bucle siempre ejecutar el cdigo del cuerpo por lo menos, una vez. Asegrate de usar el
punto y coma al final de la expresin while.



El uso de los bucles

En Java 5, los bucles for tienen una segunda estructura. Nosotros llamaremos al viejo estilo,
"bsico", y al nuevo estilo "bucle mejorado" aunque Sun se refieren a el como for-each.

Dependiendo de la documentacin que uses (Sun incluida) vers los dos trminos
paralelamente con for-in. Los trminos for-in y for-each se refieren al mismo for mejorado.
El bucle bsico de for es ms flexible que su homnimo mejorado, pero el mejorado fue
diseado para realizar iteraciones a travs de colecciones y arrays.



11.5 Estamento for, o for-in (el bucle bsico)

Este estamento es til cuando sabes de antemano las veces que se ejecutar el cdigo dentro
del bloque. Este estamento consta de tres partes adems del cuerpo del bucle:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 106
Declaracin e inicializacin de la variable
La expresin booleana
La iteracin
Las tres partes estn separadas por punto y coma. Los siguientes ejemplos demuestran un
bucle for. El primer ejemplo muestra las partes de un bucle for en pseudo cdigo, y la segunda,
un ejemplo tpico.





El for bsico: declaracin e inicializacin

La primera parte del estamento te permite declarar e inicializar cero, una o mltiples variables
del mismo tipo dentro del parntesis despus de for. Si declaras ms de una variable del
mismo tipo, entonces las tendrs que separar con ; (punto y coma) tal como sigue:



La declaracin e inicializacin ocurre antes que nada en el bucle. Y mientras las otras dos
partes, la evaluacin booleana y la iteracin, se ejecutarn con cada vuelta de bucle, la
declaracin slo suceder una vez al comienzo. Tambin tienes que saber que la vida de las
variables declaradas en el bucle, terminan con el bucle.

Este ejemplo lo demuestra:



Test.java:19: cannot resolve symbol
symbol : variable x
location: class Test
System.out.println(x);
^







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 107
El for bsico: la expresin booleana

La siguiente seccin que se ejecuta es la expresin de la condicin, la que (como en todos los
test condicionales) debe evaluar un valor booleano. Solo puedes tener una expresin lgica,
pero puede ser compleja. Observa el cdigo:



Este cdigo era vlido, pero el siguiente no lo es:



El compilador arrojar:

TestLong.java:20: ';' expected
for (int x = 0; (x > 5), (y < 2); x++) { }
^

La regla para recordar esto: Solo puedes tener una expresin lgica.

En otras palabras, no puedes usar mltiples evaluaciones separadas por comas, aunque las
otras dos partes del estamento puedan tener mltiples partes.


El for bsico: el operador de iteracin

Despus de cada ejecucin del cuerpo del bucle, se ejecuta la expresin de internacin. Esto es
donde le dices lo que quieres que ocurra en cada iteracin del bucle. Recuerda que siempre
ocurre despus de que el bucle se complete. Mira lo siguiente:



El cdigo precedente se ejecuta solo una vez. La primera vez, dentro del estamento x vale
cero, luego se evala para ver si es menor que uno (lo que es cierto) para despus ejecutar el
cuerpo del bucle. Despus de que el cuerpo se haya ejecutado, la iteracin se ejecuta
incrementando x en 1. Lo siguiente que toca es evaluar x, pero el resultado ahora es falso, la
ejecucin del bucle termina.

Ten en cuenta que, salvo una salida forzada, la evaluacin de la iteracin y la evaluacin del
booleano son las dos ltimas cosas que ocurre en un bucle for.

El ejemplo de salida forzada pueden ser un break, un return, un System.exit() o una excepcin,
que causar una salida repentina sin ejecutar la expresin de iteracin.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 108
Observa este cdigo:



Al ejecutar este cdigo, se arroja en pantalla:

in for loop

El estamento imprime una vez, porque un return causa que se abandone la ejecucin no solo
la iteracin sino que tambin todo el mtodo. As que la iteracin de la expresin nunca se
ejecuta en este caso.

La siguiente tabla muestra el resultado de una salida forzada del bucle:





El for bsico: puntualizaciones

Ninguna de las tres secciones de la declaracin son obligatorias! El siguiente ejemplo es
perfectamente vlido (aunque no es buena prctica):



En el ejemplo todas las partes estn vacas as que este bucle es infinito. Es importante saber
que con la ausencia de la inicializacin y la seccin de incremento, el bucle actuar como
bucle while. El siguiente ejemplo lo demuestra:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 109
El siguiente ejemplo demuestra que un bucle for con mltiples variables, y deben ser del
mismo tipo. Recuerda que las variables declaradas en el estamento for son todas locales y no
pueden ser usadas fuera del for.



La ultima cosa que aadir es que las tres secciones de for son independientes unas de otras.
Las tres expresiones no necesitan operar la misma variable, aunque es lo tpico. Pero hasta el
operador de iteracin, el cual es llamado errneamente el operador de incremento, no
necesita incrementar o asignar nada, puedes poner un estamento virtual para lo que quieras
que ocurra en cada iteracin del bucle. Mira lo siguiente:



Lo anterior imprime:

iterate
iterate



11.5.1 El for mejorado (para arrays, for each)
Fue introducido para Java 5 y est especializado en simplificar el trabajo de recorrer una
coleccin o un array en un bucle. En este tema vamos a centrarnos en el uso de este nuevo for.
Lo visitaremos nuevamente, cuando veamos las colecciones, que es donde esta nueva revisin
se siente como en casa.
En lugar de tener tres componentes, la versin actualizada tiene dos. Repasemos la vieja forma
y luego usaremos la nueva:


Resultado:

12341234







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 110
Formalmente, vamos a describir cmo funciona:



Las dos piezas del estamento son:

declaracin: es un bloque recin declarado de una variable, de tipo compatible con los
elementos del array al que se est accediendo. Esta variable estar disponible dentro
del bloque, y su valor ser el mismo que el elemento actual del array.

expresin: debe evaluar el array que quieres recorrer. Podra ser un array, o un
mtodo que devuelve un array. El array puede ser de cualquier tipo, objetos,
primitivos o arrays de arrays.
Usando las definiciones anteriores, echemos un vistazo a algunas declaraciones vlidas y no
vlidas:



El for actualizado asume que salvo en una salida forzosa del bucle, siempre recorrers todos
los elementos del array. El siguiente apartado de break y continue se aplican a los dos tipos de
for.



11.6 El uso de break y continue

El uso de break y continue son usadas para parar todo el bucle o slo la iteracin actual
(continue). Normalmente si usas break o continue, lo hars en una evaluacin if dentro del
bucle, y si alguna condicin se convierte en true (o false dependiendo del programa) querrs
salir inmediatamente. La diferencia entre ellos es si querrs continuar o no con la iteracin o
saltar al primer estamento despus del bucle y continuar desde all





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 111
El estamento break hace que el programa detenga la ejecucin de su bucle inmediato y
comienza a procesar la siguiente lnea de cdigo.

El estamento continue hace que slo la iteracin actual del bucle inmediato se detenga y
comience por la siguiente evaluacin. Cuando usamos un continue en un bucle for, tienes que
considerar los efectos que continue tiene en la operacin del bucle. Examina este ejemplo:



La pregunta es, esto es un bucle sin fin? La respuesta es no. Cuando llegamos al continue, la
iteracin aun est ejecutndose. Se ejecuta a travs de la iteracin actual de manera natural.
As que el ejemplo anterior, la variable i todava incrementar despus de que la condicin (i <
10) sea evaluada de nuevo. La mayora de las veces, un continue se usa dentro de un if tal
como se muestra:








Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 112
Como nota personal, tengo que aadir que no vi claro el uso de continue, as que desarroll el
siguiente cdigo:



y esto me produjo la siguiente salida:

Inside loop 0
Wea: 0
Inside loop 1
Wea: 1
Inside loop 2
Wea: 2
Inside loop 3
Wea: 3
Inside loop 4
Wea: 4
Inside loop 5
Inside loop 6
Wea: 6
Inside loop 7
Wea: 7
Inside loop 8
Wea: 8
Inside loop 9
Wea: 9

As pude observar, que cuando la condicin se cumple, el resto del bloque no se ejecuta (se
ignora cuando i==5), volviendo el punto de ejecucin del estamento for, donde se continua la
iteracin hasta el final.








Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 113
11.6.1 Estamentos sin etiquetas

Los estamentos break y continue pueden estar etiquetados o no. Quizs lo ms comn es que
no estn etiquetados. Como dijimos antes, un estamento break (sin etiqueta) saldr del ms
inmediato bucle y seguir con la siguiente lnea de cdigo despus del cuerpo. El siguiente
ejemplo demuestra un estamento break:



En este ejemplo, el estamento break esta sin etiquetar. El siguiente ejemplo es un ejemplo
de continue etiquetado:



En este ejemplo, se est leyendo el campo de un fichero. Cuando encuentra un error, el
programa salta al siguiente campo de la fila y usa el estamento continue para volver al bucle
(sino es el final de la fila) y mantiene la lectura de varios campos. Si el estamento break se
hubiera puesto en su lugar, el cdigo habra parado de leer al encontrar el error y se hubiera
terminado la lectura del fichero.

El estamento continue es una manera de decir "Esta iteracin en particular necesita parar,
pero no todo el conjunto. No quiera finalizar el resto de la iteracin".



11.6.2 Estamento con etiquetas

Aunque muchos estamentos en Java pueden ser etiquetados, lo ms comn es usar las
etiquetas con bucles como for o while, en conjuncin con break y continue. Una etiqueta debe
ser puesta justo antes del estamento etiquetado, y consiste en un identificador valido que
finaliza con dos puntos (:).







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 114
Tienes que entender la diferencia entre etiquetado y sin etiquetar. La etiquetacin solo son
necesarias en situaciones donde tienes un bucle anidado, y necesitas indicar cul de los bucles
quieres romper, o a cul de ellos quieres continuar en la siguiente iteracin. Un estamento
break saldr del bucle etiquetado, lo opuesto al bucle inmediato, si un break esta combinado
con una etiqueta. Un ejemplo de como parece una etiqueta es lo siguiente:



La etiqueta debe de cumplir las mismas reglas que las variables en lo que se refiere al nombre.
La sintaxis para el uso de la etiqueta en conjuncin con un estamento break es la palabra
break , despus el nombre de la etiqueta, seguido de un punto y coma.

Un ejemplo ms completo es el que sigue:



El cdigo produce la siguiente salida:

Hello
Good-Bye





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 115

En este ejemplo, la palabra Hello ser imprimida una vez. Luego la etiqueta de break ser
ejecutada y el flujo saldr del bucle etiquetado outer. La siguiente lnea de cdigo
imprimir Good-Bye. Veamos lo que pasa si el estamento continue se usa en lugar del break. El
siguiente cdigo es similar al anterior, con la excepcin de la sustitucin de break por
continue:



Al ejecutar el cdigo, se imprime:

Hello
Hello
Hello
Hello
Hello
Good-Bye

En este ejemplo, Hello se imprimir cinco veces. Despus de que el estamento continue se
haya ejecutado, el flujo continua con la siguiente iteracin del bucle identificado en al
etiqueta. Finalmente, cuando la condicin en el bucle ms exterior se evala a false, este bucle
terminara con la impresin de Good-Bye.








Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 116
12. Excepciones
Una vieja mxima del desarrollo de software dice que del 80% del trabajo se usa un 20%. El
80% se refiere al esfuerzo para evaluar y manejar errores. En muchos lenguajes, escribir
programas que evalen y manejan errores es tedioso e hincha el cdigo fuente de la aplicacin
para hacerlo tan confuso como un espagueti.
Aun as, la deteccin y manejo de errores debe ser el ingrediente ms importante para la
robustez de una aplicacin. Java provee a los desarrolladores con elegantes mecanismos de
manejo de errores que produce un eficiente y organizado cdigo: manejo de excepciones
(exception handling).
Las excepciones permiten a los desarrolladores detectar errores fcilmente sin escribir cdigo
especial para evaluar valores de retorno. Incluso mejor, te permite manejar la excepcin de
manera separada y transparente del cdigo generado por la excepcin. Tambin te permite
usar el mismo manejador de excepciones para hacer frente a una serie de posibles
excepciones.


12.1 El estamento try catch
Antes de empezar, introduzcamos algo de terminologa. El termino excepcin significa
condicin excepcional, y es un suceso que altera el fluido normal del programa. Un puado de
cosas pueden conducir a una excepcin, incluyen fallo de hardware, fuente de recursos
agotadas, y unos buenos bugs. Cuando ocurre un evento excepcional en Java, se dice que se ha
arrojado una excepcin. El cdigo responsable de hacer excepciones se llama "manejador de
excepciones" en ingls "exception handler", y atrapa la excepcin arrojada.
El manejador de excepciones funciona transfiriendo la excepcin del programa al manejador
de excepciones apropiado cuando sucede el evento. Por ejemplo, si llamas a un mtodo que
abre una fila y la fila no puede ser abierta, la ejecucin del mtodo se detendr, y el cdigo
que escribiste para manejar la situacin se ejecutara. Para ello, necesitamos una manera de
decirle a la JVM que el cuando suceda una cierta excepcin, ejecute el cdigo. Para hacer esto
usamos las palabras claves try y catch. El try se usa para definir un bloque de cdigo donde
puede ocurrir la excepcin. Este bloque se le llama regin guardada (lo que significa que el
cdigo peligroso va aqu). Una o ms clausulas catch especifican la excepcin (o grupo de
excepciones, ms tarde veremos ms) a un bloque de cdigo que lo maneje. Aqu se muestra
un ejemplo en pseudocdigo:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 117


En este pseudocdigo, la lnea 2 hasta la 5 constituye la regin gobernada por try. La lnea 7 es
el manejador de la excepcin de tipo MyFirstException. La lnea 12 es un manejador de
excepciones de tipo MySecondException. Date cuenta de que el bloque catch sigue al try. Esto
es obligatorio, si tienes uno o ms bloques catch, deben ir inmediatamente detrs de try.
Adems, los bloques catch deben ir uno detrs del otro, sin estamentos o bloques de por
medio. Tambin el orden de los catch importa, como veremos ms tarde.
La ejecucin de la regin de seguridad empieza en la lnea 2. Si el programa se ejecuta sin
excepciones, saltar a la lnea 15. Sin embargo, si la primera lnea 2 hasta la 5 arroja una
excepcin de tipo MyFirstException, la ejecucin ser inmediatamente transferida a la lnea 7.
Desde la lnea 8 a la 10 se ejecutarn todas las instrucciones del bloque, y luego la ejecucin
continuara en la lnea 15 y continuar.
Fjate que si una excepcin ocurre en la lnea 3 del bloque, el resto de lneas en el try no sern
ejecutadas. Una vez que el control salte al bloque catch, no se volver a ejecutar el bloque try.
Esto es exactamente lo que t quieres, creo... Imagina que tu cdigo se parece a esto en
pseudo cdigo:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 118
El pseudocdigo demuestra cmo funcionan normalmente las excepciones. El cdigo que
depende de un riesgo en la operacin (como llenar una tabla con los datos de un fichero en
internet) esta agrupado dentro del bloque try de tal manera que si, por ejemplo, la primera
operacin fracasa, no vas a intentar continuar ejecutando otro cdigo que seguramente va a
fallar tambin. El pseudocdigo del ejemplo no te va a dejar leer un fichero si no hay internet
en primer lugar.
Uno de los beneficios de usar un manejador de excepciones es que el cdigo para manejar en
cualquier excepcin en particular puede ocurrir en la regin gobernada, necesite ser reescrita
solo una vez. Volviendo a nuestro cdigo anterior, pueden haber tres sitios en nuestro
bloque try que pueda generar una MyFirstException, pero si esto ocurre, ser manejado en el
mismo bloque catch (lnea 7). Hablaremos de ms beneficios de la excepcin casi al final de
este tema.

12.1.1 El uso de finally
Aunque try y catch proveen de un fabuloso mecanismo para atrapar y manejar excepciones,
nos queda el problema de como limpiar lo que deja una excepcin. Dado que la ejecucin
dentro del bloque try se interrumpe sbitamente si hay una excepcin, no podemos limpiar el
cdigo del bloque try y esperar que sea ejecutado. Casi que es una mala idea poner nuestro
cdigo de limpieza en cada bloque catch, veamos el motivo.
El manejador de excepciones no son el lugar adecuado para limpiar el bloque try porque cada
manejador requiere su propia copia para limpiar el cdigo. Por ejemplo, si algn puerto o
fichero se queda abierto en la regin de seguridad, cada excepcin debera cerrar ese fichero o
ese puerto. Sera ms fcil olvidar la limpieza y tambin un montn de cdigo redundante.
Para solucionar este problema, Java provee del bloque finally.
El bloque finally encierra un cdigo que siempre ser ejecutado despus del bloque try, sin
importar si hay una excepcin o no. Aunque hubiera un return al final del bloque try, se
ejecutara justo despus del return, y antes de que el return se ejecute!
Este es el lugar correcto para meter tu cdigo de limpieza, cerrar tus puertos o cerrar tus
ficheros, etc... Si el cdigo se ejecuta sin excepciones, el cdigo finally se ejecutar
inmediatamente despus. Veamos otro ejemplo:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 119

Igual que antes, la ejecucin empieza en la primera lnea del bloque try, la lnea 2. Si no hay
excepciones en el bloque try, la ejecucin prosigue por la lnea 11, la primera lnea del
bloque finally. Por otra parte, si MySeconException arroja una excepcin mientras el
bloque try se est ejecutando, la ejecucin prosigue en la primera lnea del manejador de
excepciones, la lnea 8 de catch. Despus de que todo el cdigo en catch se haya ejecutado, el
programa prosigue en la lnea 11, la primera lnea de finally.
Repite despus de mi: el bloque finally siempre se ejecuta! OK, tenemos que afinar un poco,
pero por ahora la idea de que finally siempre se ejecuta ha quedado clara. Tanto si se coge la
excepcin, como si no, finally siempre se ejecuta. Ms adelante veremos unos pocos
escenarios donde finally podra no completarse.
Recuerda, la clusula finally no es obligatoria. Si no tienes, el cdigo, compilar perfectamente.
De hecho, no todos los actos de un cdigo tienen que ser limpiados despus de que un
bloque try se ejecute, as que la clusula finally no es obligatoria. Tambin, porque el
compilador no exige tampoco la clusula catch, algunas veces querrs ejecutar el cdigo que
tiene un try para terminar en el finally. Esta clase de programacin es til cuando la excepcin
devuelve el flujo al mtodo que lo invoc, como explicaremos en la siguiente seccin. El uso
de finally te permite limpiar el cdigo ejecutado aunque no haya clausula catch.
Este cdigo muestra un try con finally pero sin catch:


Este cdigo muestra un try, catch y finally:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 120


El siguiente cdigo ilegal muestra un try sin catch o finally:



El siguiente cdigo ilegal muestra un ejemplo de cdigo fuera de lugar:






12.1.2 Programacin de excepciones no capturadas

Por qu los catch no son obligatorios? Que ocurre tras una excepcin en un bloque try donde
no hay catch? No hay requerimientos para que en tu cdigo haya un catch para cada excepcin
que pueda ser arrojada al correspondiente bloque try. El hecho, es que es dudoso que puedas
hacer tal hazaa! Si un mtodo no provee de una clausula catch en particular, a ese mtodo se
le llama "ducking" y lo que hace es pasarle la pelota a otro mtodo. As que, qu ocurre?
Cuando un mtodo, llama a otro, y esto a otro... la ejecucin comienza, obviamente, por el
ultimo mtodo invocado. Cuando uno de estos mtodos invocados tiene una excepcin, esta
excepcin se recorre hacia atrs, esperando a ser atrapada. Si esta excepcin llega al primer
mtodo, y no es atrapada, estalla deteniendo la ejecucin del programa.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 121



Observa este ejemplo donde se crea una clase main que ejecuta el mtodo reverse sin
proporcionarle argumento con el que trabajar (lnea 8).

De la lnea 8 saltamos al mtodo reverse (lnea 23) que arroja una excepcin de tipo
NadaQueDevolver. En la lnea 25, comprueba que la longitud de la cadena es menor que
uno y arroja la excepcin.

En la lnea 41 se crea la clase NadaQueDevolver que hereda la clase Exception. El constructor
de la clase hace una llamada (super) pasndole como parmetro un texto.

Volvemos a la lnea 10 donde se coge la excepcin y se imprime Excepcin arrojada: No hay
texto que devolver.

Finalmente se ejecuta el bloque finally.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 122
12.1.3 Definiendo excepciones

Hemos discutido las excepciones como concepto. Sabemos que se arrojan cuando surge algn
tipo de problema, y sabemos el efecto que tienen en el flujo de un programa. En esta seccin
vamos a desarrollar los conceptos ms all y el uso de excepciones en cdigo Java funcional.
Antes dijimos que una excepcin es una ocurrencia que altera el flujo normal del programa.
Pero desde que estamos usando Java, cualquier cosa que no es un primitivo, es... un objeto.
Las excepciones no, bien, esta es la excepcin que confirma la regla. Cada excepcin es una
instancia de la clase Exception en su propio rbol de jerarqua. En otras palabras, las
excepciones son siempre una subclase de java.lang.Exception.

Cuando se arroja una excepcin, un objeto del subtipo particular se instancia y maneja la
excepcin como un argumento para la clusula catch.

Un catch se parece a esto:



En este ejemplo, es una instancia de la clase ArrayIndexOutOfBoundsException. Como
cualquier otro objeto, puedes llamar a sus mtodos.



12.1.4 Jerarqua de las excepciones

Todas las clases de excepciones son subtipos de la clase Exception. Esta clase deriva
de Throwable (la cual deriva de la clase Object). Esta imagen representa la jerarqua de las
clases Exception:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 123
Como puedes observar, hay dos subclases que derivan de Throwable: Exception y Error. Las
clases que derivan de Error representan situaciones inusuales que no son causadas por errores
del programa, e indican cosas que normalmente no pasaran durante la ejecucin de un
programa, como por ejemplo, que la JVM se quede sin memoria. Normalmente tu aplicacin
no puede manejar este tipo de errores, as que no puede recuperarse. No se te pide que los
manejes. Si tu cdigo no los maneja, (normalmente no) compilar sin problemas. Quizs hayas
pensado en condiciones excepcionales, los errores tcnicamente no son excepciones porque
no derivan de la clase Exception.

En general, una excepcin representa algo que ocurre como resultado no deseado por un error
de programacin, ya que no se considera alguna condicin que pueda estar presente. Por
ejemplo, si en tu aplicacin se supone que va a comunicarse con otra aplicacin en otro
ordenador, y este, no contesta, esta excepcin no la causa un bug. Estas excepciones son un
caso especial porque algunas veces indican error del programa. Tambin pueden presentarse
casos raros para manejar excepciones en condiciones excepcionales. En tiempo de ejecucin,
las excepciones son discutidas con gran detalle, ms adelante en este tema.

Java provee de muchas clases de excepciones, la mayora con nombres bastantes descriptivos.
Hay dos maneras de conseguir la informacin de una excepcin. La primera es desde el tipo de
excepcin en si misma. La siguiente es de la informacin que obtienes del objeto en excepcin.
La clase Throwable (en lo alto de la herencia) provee a sus descendientes con algunos mtodos
que son tiles para manejar las excepciones. Uno de ellos es printStackTrace(). Como
imaginabas, puedes invocar los mtodos de una excepcin, como vimos en un ejemplo
anterior, se imprimir el seguimiento de la excepcin.

Ya vimos que una llamada a la pila empieza desde abajo para terminar en el primer mtodo
que invoco a los dems. Te dars cuenta de que printStackTrace() imprime la mayora de los
mtodos recientes y luego continua descendiendo, imprimiendo el nombre de cada mtodo de
la pila.



12.1.5 Manejando una clase completa de la jerarqua de excepciones

Ya hemos visto que la palabra clave catch te permite especificar un tipo en particular de
excepcin. Puedes capturar ms de un tipo de excepciones en una nica clusula. Si la clase de
excepcin especificada en catch no tiene subclases, entonces solo se atrapar esa excepcin
en concreto. Sin embargo, si la clase especificada en catch tiene subclases, las subclases
tambin sern atrapadas.

Por ejemplo, la clase IndexOutOfBoundsException (se da cuando el ndice especificado de un
array sale de su rango) tiene dos subclases,
ArrayIndexOutOfBoundsException y StringIndexOutOfBoundsException. Podras desear escribir
un cdigo que maneje la excepcin, pero no sabes que excepcin se est arrojando (cual
subclase). En este caso, puedes escribir un catch como este:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 124


Si cualquier cdigo en el bloque try arroja:
ArrayIndexOutOfBoundsException o StringIndexOutOfBoundsException, la excepcin ser
atrapada y manejada. Esto puede ser conveniente, pero podra ser usado por separado. Al
especificar una excepcin de la superclase en la clusula catch, ests descartando informacin
valiosa de tu excepcin. Puedes, naturalmente, averiguar como ocurri esa excepcin en la
clase, pero si vas a hacer eso, es mejor escribir una clausula catch para cada tipo de excepcin.

Si tienes una jerarqua de excepciones compuesta de una superclase y un numero de subtipos,
y ests interesado en manejar uno de los subtipos de una manera especial, necesitas escribir
solo dos clausulas catch.

Cuando se arroja una excepcin, Java intentar encontrar la excepcin del tipo que encaje con
la clusula catch. Si no la hubiese, entonces ir a por su supertipo. Si tampoco existiese,
entonces se propagar la excepcin hasta que pueda ser manejada llegando a interrumpir la
ejecucin del programa sino se detuviese.

Este proceso se le conoce como la excepcin que encaja con la bsqueda. Veamos un ejemplo:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 125


Este programa intenta abrir un fichero para lectura de algn dato. Abrir y leer ficheros puede
generar muchas excepciones, la mayora de ellas son de algn tipo de IOException. Imagina
que en este programa estamos interesados en saber slo cuando hay una excepcin en
concreto: FileNotFoundException . De otra manera no sabemos de que problema se trata.

FileNotFoundException es una subclase de IOException. As que podemos manejar en la
clusula catch todos los subtipos de IOException, pero podramos evaluar la excepcin que
determina si fue una FileNotFoundException . As que codificamos una excepcin
exclusivamente para FileNotFoundException y separado de la excepcin que maneja los dems
subtipos de excepcin.

Este cdigo generado para FileNotFoundException ser manejado por catch comenzando en la
lnea 10. Si genera otra clase de IOException, a lo mejor, EOFException, que es subclase
de IOException, ser manejado por el catch de la lnea 15. Si cualquier otra excepcin es
generada, tal como excepciones en tiempo de ejecucin, no ser capturada y se propagara por
la pila.

Date cuenta que la clusula para FileNotFoundException ha sido puesto antes
que IOException. Esto es muy importante. Si no lo hiciramos, el programa no compilara. Los
manejadores especficos de excepciones deben ser puestos delante siempre de los
manejadores genricos. Lo siguiente no compilar:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 126


El compilador arrojara esto:

TestEx.java:15: exception java.io.FileNotFoundException has
already been caught
} catch (FileNotFoundException ex) {
^



12.1.6 Declaracin de Excepciones e Interfaces Pblicas

Como sabemos que mtodos que arrojan una excepcin y que podemos capturar? Un mtodo
debe especificar el tipo y la cantidad de argumentos que acepta y lo que devuelve, las
excepciones que un mtodo puede arrojar tienen que ser declaradas (al menos las
excepciones son subclases de RunTimeException). La lista de excepciones declaradas es una
parte de la interfaz pblica del mtodo. La palabra clave throws se usa para enumerar la lista
de excepciones que un mtodo puede arrojar:



Este mtodo tiene un tipo de retorno void, no acepta argumentos y declara que puede arrojar
dos tipos de excepciones: MyException1 y MyException2. Solo porque el mtodo declare que
arroja excepciones, no quiere decir que siempre las est arrojando. Solo dice que podra.

Supn que tu mtodo no arroja directamente una excepcin, pero llama a un mtodo que lo
hace. Puedes elegir manejar o no la excepcin. Si declaras la excepcin que tu mtodo puede
conseguir de otro mtodo, y no provees de un try-catch, entonces el mtodo programar la
excepcin.

Cualquier mtodo que pueda arrojar una excepcin (que sea subclase de RunTimeException)
debe declarar la excepcin. Eso incluye mtodos que no estn arrojando excepciones
directamente, pero estn pasando la excepcin a otro mtodo. Si pasas la excepcin, ests
arrojando RunTimeException. Como las subclases estn exentas de implementarlo, el
compilador no va a mirar si lo has hecho. Todas las excepciones RunTimeException son
consideradas "comprobadas", porque el compilador lo hace para estar seguro de que has
reconocido que algo malo podra pasar aqu.

Recuerda:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 127
Cada mtodo debe manejar todas las excepciones comprobadas suministrando un catch o
listando mediante throws cada excepcin.

Esta regla es requerida en Java. Se la conoce como "manejar o declarar", algunas veces se la
llama tambin "atrapar o declarar".

Nuevamente, algunas excepciones estn exentas de esta regla. Un objeto de
tipo RunTimeException puede ser arrojado desde cualquier mtodo sin que se especifique
como parte del mtodo o de la interfaz pblica (y no se necesita ningn try-catch). Incluso si
un mtodo no declara RunTimeException , el mtodo que invoca tampoco tiene obligacin de
declararlo o manejarlo. RunTimeException , Error, y todos sus subtipos de excepciones no
comprobadas y esta clase de excepciones no tienen que ser manejadas. Por ejemplo:



Fjate en myMethod1(). Ya que EOException es subclase de IOException y este es de Exception,
debe ser declarada como una excepcin que pueda arrojar este mtodo. Pero de donde viene
la excepcin? La interfaz publica para el mtodo myMethod2() invocada aqu, declara que una
excepcin de este tipo puede ser arrojada. Sin embargo ese mtodo actualmente arroja la
excepcin por si misma o invoca otro mtodo que la arroja que no es importante para
nosotros, lo nico que sabemos es que tenemos que atrapar la excepcin o declarar que se
puede arrojar. El mtodo myMethod1() no atrapa la excepcin, as que la declara. Ahora
veamos otro ejemplo valido:



De acuerdo con lo comentado, este mtodo puede arrojar un NullPointerException. Ya
que RunTimeException es superclase de NullPointerException, y esto es una excepcin no
comprobada, no necesita ser declarada. Podemos ver que myMethod3() no declara ninguna
excepcin.

Las excepciones en tiempo de ejecucin son excepciones no comprobadas. Todas las dems
excepciones son comprobadas, y no derivan de java.lang.RuntimeException. Una excepcin
debe ser atrapada en alguna parte del cdigo. Si invocas un mtodo que arroja una excepcin
pero no la atrapas, el cdigo no compilara. Eso es porque lo llamamos excepciones
comprobadas, el compilador se asegura que son manejadas o declaradas.

Hay un gran nmero de mtodos en las libreras de Java 2 que arrojan excepciones, as que a
menudo escribirs manejadores de excepciones para hacer frente a estas, generados por
mtodos que ni tan siquiera escribiste.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 128
Tambin puedes arrojar excepciones t mismo, y la excepcin tambin puede ya existir en el
API de Java, o uno creada por ti. Para crear tus propias excepciones, simplemente
heredas Exception (o una de sus subclases) tal como sigue:



Este cdigo mosquear al compilador:

TestEx.java:6: unreported exception MyException; must be caught
or
declared to be thrown
throw new MyException();
^

Necesitas saber cmo se compara un Error con excepciones comprobadas y sin comprobar. Los
objetos de tipo Error no son objetos Exception, aunque ellos presentan unas condiciones
especiales. Exception y Error comparten la misma superclase, Throwable y ambas pueden ser
arrojadas usando throws. Cuando un Error o una subclase de Error es lanzada, no se
comprueba. No se le requiere atrapar objetos Error o subtipos. Tambin puedes lanzar
errores t mismo (aunque aparte de una AssertionError no creo que quieras usar otra, quizs
un OutOfMemoryError?) y puedes capturarla.

Lo siguiente compila perfectamente:



Si estuviramos lanzando una excepcin comprobada en lugar de un Error, entonces el
mtodo doStuff() necesitara declarar la excepcin. Pero recuerda, los errores no son subtipos
de Exception, no necesitan ser declarados. Si quieres declralos, pero al compilador le dar lo
mismo quien o de donde sale un error.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 129
12.1.7 Relanzando la misma excepcin

Igual que puedes lanzar una nueva excepcin desde un catch, tambin puedes arrojar la misma
excepcin que atrapas. Aqu la clusula catch lo hace:



Las dems clusulas catch asociadas con el mismo try sern ignoradas, si existiese un finally, se
ejecutara y la excepcin volvera a ser arrojada desde el mtodo que lo invoc. Si lanzas una
excepcin comprobada desde un catch, debes tambin declarar la excepcin! En otras
palabras, debes manejar y declarar, lo opuesto a declarar o manejar. Lo siguiente es ilegal:



El mtodo doStuff() es quien claramente el que atrapa la excepcin IOException, pero el
compilador va a decir, "si, muy bien, veo que atraparas la excepcin, pero no es suficiente. Si
quieres relanzar la excepcin, tendrs que declararla".





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 130


En este programa se le pasa mediante parmetros la comida, y si no es del agrado, lanzar una
excepcin.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 131
A continuacin expongo como lanzar una aplicacin con Eclipse adjuntando parmetros:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 132


y el ejemplo arroja como resultado:

No esta mal tu eleccion.
Fin de la ejecucion.

Si ponemos otros manjares, como "piedras palos pelo" el programa arroja:

Esa comida no nos gusta!
Fin de la ejecucion.




12.1.8 Definicin de conceptos, excepcin y error

Comencemos con la excepciones ms comunes, NullPointerException. Tal como vimos, esta
excepcin ocurre cuando intentas acceder a un objeto usando una variable de referencia con
el valor de null. No hay manera de que el compilador tenga la esperanza de encontrar este
problema antes de ejecutar el programa (o sea, en tiempo de ejecucin). Veamos lo siguiente:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 133
Seguramente el compilador encontrara el problema en este programita! No, es cosa tuya. El
cdigo compilara perfectamente y la JVM arrojara un NullPointerException cuando intente
invocar el mtodo length().

Antes discutimos la llamada a la pila. Como recordars, usamos la convencin de
que main() estara al final de la pila, y que como main() invoca otro mtodo, y ese mtodo
invoca otro, etc... la pila crece. Naturalmente la pila reside en la memoria, e incluso si tu
sistema operativo te da un 1GB de RAM para tu programa, la cantidad de memoria aun es
finita. Es posible crecer la pila hasta ocupar toda la RAM de tu SO para guardar la pila. Cuando
esto pasa, lo que obtienes es un (espera para verlo...), StackOverflowError. La manera ms
comn para que esto ocurra es crear un mtodo recursivo. Un mtodo recursivo es aquel que
se invoca as mismo en el cuerpo del mtodo. Mientras que eso puede sonar a locura, es una
tcnica muy extendida para buscar y ordenar algoritmos. Mira este cdigo:



Como puedes ver, si cometes el error de invocar al mtodo go(), el programa caer en un
agujero negro, go() invocara a go() hasta, no importa cuanta memoria tengas, que consigas
un StackOverflowError. Nuevamente, solo la JVM sabe cuando esto ocurre, y la JVM ser la
fuente de este error.



12.1.9 Programando el arrojo de excepciones

Fjate que digo "programando" como queriendo decir:

"Creado por una aplicacin y/o API por un desarrollador"

Por ejemplo, muchas clases en el API de Java tienen mtodos que toman cadenas como
argumento, y convierten estas cadenas en nmeros primitivos. Un buen ejemplo de estas
clases son llamadas clases de envoltorio.

Algunos programadores escribieron la clase java.lang.Integer y crearon mtodos
como parseInt() y valueOf(). El sabio programador decidi que si a uno de estos mtodos le
pasaba una cadena que no poda ser convertida en nmero, el mtodo arrojara
un NumberFormatException. El cdigo parcialmente implementado se parece a esto:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 134
Otros ejemplos de excepciones programadas incluye una AssertionError (vale, no es una
excepcin, pero se arroja programando), y arroja IllegalArgumentsException. El hecho, nuestro
mtico desarrollador del API podra usar un IllegalArgumentsException para su parseInt(), pero
devuelve NumberFormatException que hereda IllegalArgumentsException, y es un poco ms
preciso, as, en este caso, usando NumberFormatException da soporte a la idea discutida
antes: que cuando tienes una excepcin en una jerarqua, deberas usar la excepcin ms
precisa que puedas.

Naturalmente como vimos antes, puedes hacer tus propias excepciones, y arrojarlas cuando
quieras. Estas excepciones caseras tambin entran en la categora de excepciones
programadas.

Excepciones ms comunes:

Excepcin Descripcin Arrojado por
ArrayIndexOutOfBoundsException Arrojado cuando se intenta acceder a
un array con un valor ndex equivocado
(negativo o mayor que la longitud del
array)
JVM
ClassCastException Arrojado cuando se intenta castear una
variable de referencia de un tipo que no
pasa el test ES-UN
JVM
IllegalArgumentException Arrojado cuando un mtodo recibe un
argumento formateado de diferente
manera que lo que espera el mtodo.
Programado
IllegalStateException Arrojado cuando el elemento de
entorno no es el mismo que la
operacin que se intenta hacer, por
ejemplo un Scanner que ha sido
cerrado.
Programado
NullPointerException Arrojado cuando se intenta acceder a
un objeto con una variable de
referencia null.
JVM
NumberFormatException Arrojado cuando un mtodo que
convierte una cadena a un nmero,
recibe una cadena que no puede ser
convertida.
Programado
AssertionError Arrojado cuando el test booleano
devuelve falso.
JVM
ExceptionInInitializerError Arrojado cuando se intenta inicializar
una variable esttica o un bloque.
JVM
StackOverflowError Se arroja cuando un mtodo se recurre
profundamente. Cada invocacin se
aade a la pila.
JVM
NoClassDefFoundError Arrojado cuando la JVM no encuentra la
clase que necesita por un error en la
lnea de comando, un problema de
classpath o falta una .class.
JVM






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 135
12.2 Mecanismo de aserciones

Sabes que no debes hacer suposiciones, pero no puedes evitarlo cuando estas escribiendo
cdigo. Lo haces ponindolos en comentarios:



Escribes estamentos con ellos:



Aadido al lenguaje Java 1.4, las aserciones te permiten comprobar supuestos durante el
desarrollo, sin el gasto (tu tiempo) de escribir manejadores de excepciones que asumes que
nunca pasaran una vez el programa este desarrollado.

Se supone que asumes que un nmero pasado como parmetro a un mtodo nunca ser
negativo. Mientras compruebas y limpias de errores el cdigo, quieres validar tu suposicin,
pero no quieres tener que empezar a escribir excepciones o cdigo evaluando cuando ya has
hecho el programa. Pero dejar esto sin comprobar es un riesgo. Aserciones al recate! Mira este
cdigo:



Ya que supones que ests en lo cierto, no quieres emplear ms tiempo para escribir
excepciones. Y en tiempo de ejecucin no quieres incluir ms if-else porque alcanzar el else
significa que tu lgica (lo que fuera que estaba ejecutndose antes de que este mtodo fuera
invocado) ha fallado.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 136
Las aserciones te permiten comprobar tus suposiciones durante el desarrollo, pero el cdigo
de la asercin bsicamente se evapora cuando el programa est finalizado, dejando atrs el
cdigo debugger (depurador) y borrndolo. Escribamos un mtodo para evaluar que el
argumento no daba negativo:



No slo el hacer aserciones te permite dejar tu cdigo ms legible, ya que las aserciones estn
inactivas a menos que las actives, entonces, el cdigo de arriba cuando lo compiles, quedara
como:



El funcionamiento de las aserciones es bastante simple. La asercin dar siempre true, si no,
problema! El cdigo continua ejecutndose. Pero si tu asercin no est desactivada y da falso,
entonces una excepcin tipo "que se pare el mundo" AssertionError se lanza (algo que jams
podrs manejar) entonces, puedes arreglar la lgica que te condujo a este problema.

Las aserciones vienen en dos sabores: realmente simple, y simple, como por ejemplo:



y



La diferencia entre los dos es que la versin simple aade una segunda expresin, separado del
primero (expresin booleana) por dos puntos, esta expresin de cadena se aade al Stack
trace (es el sistema que cuando salta un error, te muestra el recorrido del error). Ambas
versiones arrojan inmediatamente AssertionError, pero la versin simple te da una ayuda para
depurar el cdigo, mientras que la otra versin, solo te dice que tu lgica ha fallado.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 137
12.2.1 Reglas de expresin de las aserciones

Las aserciones pueden tener una o dos expresiones, dependiendo de si usas el modo simple, o
el realmente simple. La primera expresin debe dar siempre un valor booleano! Sigue las
mismas reglas que para el if. Todo lo que hace una asercin es una evaluacin, lo que significa
que el resultado slo puede ser verdadero o falso. Si es verdadero, no hay problema. Sino,
entonces tu suposicin era errnea y consigues un AssertionError.

La segunda expresin, solo se usa con el modo simple, que puede ser cualquier cosa que
resulte en un valor. Recuerda, la segunda expresin se usa para generar un mensaje de texto
que muestre en el Stack trace algo ms de informacin para depurar el cdigo. Funciona
como System.out.println() en el que puedes pasarle un primitivo o un objeto, y lo convertir a
cadena de texto. Debe devolver un valor!

Lo siguiente muestra una lista de expresiones vlidas y errneas para ambas clases de
aserciones, recuerda que la expresin 2 se usa slo con el modo simple, donde la segunda
expresin solo te da un poco ms de informacin sobre el detalle de la asercin:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 138
12.2.2 Aserciones, identificados o palabra clave

Si quieres usar aserciones, tienes que pensar primero como compilar con aserciones tu cdigo,
y entonces, pensar como ejecutar el programa con las aserciones activadas. Ambas requieren
Java 1.4 o superior, que nos trae el primer punto, como compilar con aserciones en tu cdigo.

Identificadores contra palabras claves

Antes de la versin 1.4, tendras que haber escrito:



Fjate que en el cdigo, asercin se usa como un identificador. Esto ya no es un problema en el
1.4. Pero no puedes usar palabras claves o reservadas como identificadores, empezando
con assert que es una palabra clave. El dato de esta cuestin es que puedes usar assert como
palabra clave o como un identificador, pero no como ambas.



El uso de javac (Compilador de Java) con assert

El compilador de Java usar siempre assert como palabra clave por defecto. A menos que le
digas lo contrario, el compilador generar un error si encuentra la palabra assert usada como
identificador. Sin embargo, puedes decirle al compilador que le estas dando una cdigo
antiguo y que quisieras que lo compilase a la antigua usanza. Digamos que haces un arreglo a
un viejo cdigo del 1.3 que usa assert como identificador. En la lnea de comandos podras
escribir:



El compilador mostrara mensajes cuando descubra que la palabra assert se usa como
identificador, pero el cdigo compilar y se ejecutara. Supn que le dices al compilador que tu
cdigo es de la versin 1.4 o posterior, por ejemplo:



En este caso el compilador mostrar errores cuando descubra que estas usando assert como
un identificador.

Si quieres decirle al compilador que use las reglas de Java 5 puedes hacer una de estas tres
cosas:

Omitir la opcin -source la cual est por defecto, o aadir una de estas dos opciones a source:



Te das cuenta lo claro que es Sun sobre 1.5 y 5?




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 139
Si quieres usar aserciones como identificadores en tu cdigo, debes compilar usando -source
1.3. La siguiente tabla resume como el compilador de Java 5 reacciona a assert como
identificador o palabra clave:




12.2.3 Ejecucin con aserciones

Aqu tenemos algo bueno. Una vez que has escrito tu cdigo con aserciones puedes elegir
entre activarlas o no en tiempo de ejecucin! Recuerda que las aserciones estn desactivadas
por defecto.

Activas las aserciones en tiempo de ejecucin usando:



o



Enable significa activar, as que "enableassertions" es "activar aserciones".
En eclipse, los parmetros se introducen en este men:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 140


Tambin tienes que conocer la lnea de comandos para desactivar las aserciones:



o





12.2.4 Selector para activar y desactivar los assert

La lnea de comando para aserciones puede ser usada de diferentes maneras:
Sin argumentos (como en el ejemplo), que activa o desactiva las aserciones en todas
las clases, excepto para las clases del sistema.
Con el nombre de un paquete, de esta manera se especifica el paquete donde quieres
que acte (o no) la asercin.
Con el nombre de la clase, al igual que con el nombre del paquete.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 141
Puedes combinar los interruptores para decirle que active las aserciones en una clase y que no
se activen en las dems, tal como:



Esta lnea de comando le dice a la JVM que active las aserciones para todo el programa
excepto para la clase en com.geeksanonymous.Foo. Puedes seleccionar todo el paquete
haciendo:



Esta lnea le dice a la JVM que active las aserciones, pero que las desactive en el
paquete com.geeksanonymous y todos sus subpaquetes. Puede que el trmino de
subpaquetes no te sea familiar, ya que no hemos hablado de ellos. Un subpaquete es un
paquete en un directorio del paquete nombrado. Por ejemplo:



Este rbol lista:

com
geeksanonymous
twelvesteps

y tres clases:

com.geeksanonymous.Foo
com.geeksanonymous.twelvesteps.StepOne
com.geeksanonymous.twelvesteps.StepTwo

El subpaquete de com.geeksanonymous es el paquete twelvesteps. Recuerda que en Java
el com.geeksanonymous.twelvesteps se trata como un paquete distinto y que no tiene
relacin con los paquetes que hay por encima de el, tan slo estn compartiendo directorio.
La siguiente tabla muestra ejemplos para activar o desactivar aserciones en la lnea de
comandos:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 142
12.2.5 El uso apropiado para las aserciones

No todos los usos vlidos de las aserciones se consideran de uso apropiado.

Como ocurre con gran parte de Java, se puede abusar del uso de las aserciones a pesar de los
esfuerzos de los ingenieros para disuadir de hacer esto. Por ejemplo, nunca te harn manejar
una asercin que falle. Esto quiere decir que no deberas atraparla con catch para intentar
manejarla. Legalmente, sin embargo, AssertionError es subclase de Throwable, asi que puede
ser atrapado. Pero no lo hagas!! Si intentas recuperar algo, debera ser una excepcin. Para
disuadirte de que sustituyas una asercin de una excepcin, el AssertionError no te da acceso
al objeto que lo gener. Todo lo que consigues en un mensaje de texto.


No use las aserciones para validar argumentos de un mtodo pblico

Esto es un ejemplo de uso inapropiado:



Un mtodo pblico puede ser invocado desde cdigo que no controlas (o desde un cdigo que
jams has visto). Ya que los mtodos pblicos son parte de tu interface al mundo exterior, se
supone que tienes que garantizar cualquier anomala en los argumentos que el mtodo sea
forzado a tomar. Pero las aserciones no garantizan que se ejecuten (normalmente se
desactivan en las aplicaciones), el cdigo no se ejecutara si las aserciones estn desactivadas.
No quieres cdigo accesible que funcione solo condicionalmente, dependiendo de si las
aserciones estn activadas.

Si necesitas validar los argumentos de un mtodo pblico, probablemente arrojars
excepciones, es decir IllegalArgumentException, si el valor pasado al mtodo pblico no es
vlido.



Usar aserciones para validar argumentos en un mtodo privado

Si escribes un mtodo privado, seguramente escribirs algn cdigo que lo ejecute. Cuando
asumes que la lgica del cdigo es correcta, puedes evaluar la suposicin con una asercin de
esta manera:



La nica diferencia importante entre en el ejemplo anterior y este, es el modificador de
acceso. As, puedes forzar a cumplir las condiciones en los mtodos privados, pero no en los
mtodos pblicos.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 143

No uses aserciones para validar una lnea de comando tomada como argumento

Esto es realmente un caso especial. Si tu programa requiere una lnea de comandos de
argumentos, necesitars usar excepciones.



No uses aserciones en mtodos pblicos para evaluar casos que sabes que nunca podran
suceder.

Esto incluye bloque de cdigo que nunca podra ser ledo, incluyendo el default de un
bloque switch como este:



Si asumes que un cdigo en particular podra no ser ejecutado, como en el ejemplo donde hay
una asercin, entonces podras obtener un falso error porque este cdigo nunca sera
ejecutado.



No uses una asercin en expresiones que puedan causar efectos colaterales!

Esto podra ser muy mala idea:



la regla es, una asercin dejara el programa en el mismo estado que estaba antes de la
expresin! Piensa en ello. Las aserciones no garantizan que se ejecuten siempre, as que si no
quieres que tu cdigo tenga un comportamiento distinto dependiendo de si las aserciones
estn activadas, las aserciones no deben causar algn efecto.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 144
13.1 La clase String

La clave del objeto String, es que una vez creado, no puede ser cambiado, as que, que es lo
que realmente ocurre cuando un objeto String parece que ha cambiado?



Los objetos String inmutables

Empezaremos con un poco de informacin de trasfondo sobre las cadenas. El manejo de
caracteres es un aspecto muy fundamental en la mayora de los lenguajes de programacin. En
Java, cada carcter en una cadena es un carcter Unicode de 16 bits. Ya que los caracteres
Unicode son de 16 bits (no los escasos 7 u 8 bits que ASCII provee), el alfabeto internacional de
caracteres se representa como Unicode.

En Java, las cadenas son objetos. Al igual que cualquier objeto, puedes instanciar una
cadena con new:



Esta lnea de cdigo crea un nuevo objeto de la clase String, y le asigna la variable de
referencia s. Hasta ahora, los objetos String se parecen a cualquier otro objeto. Ahora
asignemos una cadena como valor:



Tal como esperabas la clase String tiene un buen puado de constructores, as que puedes usar
el atajo que ms te convenga:



y ya que usars cadenas todo el tiempo, incluso puedes hacer esto:



Hay algunas diferencias entre estas opciones, que veremos ms tarde, pero todas tienen en
comn que crean un nuevo objeto String, con el valor abcdef y se le asigna la variable de
referencia s. Ahora digamos que quieres una segunda referencia a un objeto String al que se
refiere s:



Todo bien hasta ahora. Los objetos String parece que se comportan de la misma manera que
los dems objetos, as que, cual es la pega?... La inmutabilidad! (Y qu diablos es la
inmutabilidad?) Una vez que has asignado un valor a String, el valor nunca cambia, es
inmutable, no cede. (Hablaremos de esto ms tarde.) Las buenas noticias es que mientras un
objeto String es inmutable, su referencia no, as que continuamos con nuestro anterior
ejemplo:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 145
Ahora espera un minuto, dijimos que era inmutable? Que es lo que pasa con "aadir un literal
al final de la cadena?" Excelente pregunta, veamos que ha pasado realmente...
La JVM tom el valor del objeto s y aadi el literal al final, dndonos el valor "abcdef mas
cosas". Ya que las cadenas son inmutables, la VM no puede dar este nuevo valor a la variable
de referencia as que lo que hace es reasignar la variable de referencia al nuevo valor.
Llegados a este punto hay dos objetos de cadena creados, el antiguo y el nuevo. Tcnicamente
son tres porque el literal para concatenar es otra cadena nueva. Pero slo tenemos referencias
a "abcdef" y "abcdef mas cosas" (referenciado ahora por s).
Que pasa sino tenamos previsto crear una segunda variable de referencia para "abcdef" antes
de que concatenramos " mas cosas"? En este caso, la cadena original aun estar en memoria
pero se la considera "perdida". Ningn cdigo de nuestro programa tiene alguna manera de
referenciarla. Acurdate de que la cadena original, es inmutable, as que no ha cambiado, lo
que si ha cambiado es la referencia de la variable s.
Otro ejemplo:


ahora:



otro:



Como ves, el uso del mtodo sobre la referencia no implica que la antigua referencia se pierda,
al contrario, si la nueva cadena no es referenciada, es la que se pierde.
La discusin que sigue contiene las claves de la inmutabilidad de las cadenas de Java.
Cubriremos ms detalle de la clase String, pero no te equivoques, lo que hemos cubierto est
lejos de ser la parte ms importante para entender cmo funcionan los objetos String en Java.
Terminaremos esta seccin representando un ejemplo de pregunta endiablada. Toma tu
tiempo para escribir en una hoja el resultado de lo siguiente:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 146

Cul sera la salida? Cuantas variables de referencia hay? Cuantos objetos String fueron
creados antes de la salida?
Respuesta: El resultado es "spring winter spring summer". Hay dos variables de
referencia, s1 y s2. Haba en total ocho objetos creados: "spring", "summer" (se pierde),
"spring summer" (se pierde), "spring fall" (se pierde), "spring summer spring" (se pierde),
"winter" (se pierde), "spring winter" (spring se pierde aqu). Solo dos de los ocho
objetos String no se pierden en este proceso.



13.1.1 String y memoria
En esta seccin vamos a ver como Java maneja los objetos String en memoria, y algunas de las
razones que dan a lugar a este comportamiento. Una de las claves de cualquier buen
programador es hacer un eficiente uso de la memoria. Ya que la aplicacin crece, es normal
que las cadenas literales ocupen grandes cantidades de memoria y a menudo son redundantes
en el universo de cadenas literales del programa.
Para hacer ms eficiente el uso de la memoria, la JVM tiene un rea especial de memoria
llamada "Piscina de constantes de String". Cuando el compilador encuentra un String literal,
verifica que en la piscina exista otra idntica. Si existe, la referencia al nuevo literal es dirigida a
la ya existente, no a la nueva creada. Ahora podemos empezar a ver por qu hacer a los
objetos String inmutables es una buena idea. Si hay varias variables de referencia apuntando a
la misma cadena aun sin saberlo, no sera buena idea cambiar el valor de la cadena.
Ahora puedes pensar "Bien eso est bien, pero que pasa si alguien sobrescribe la clase String,
no podra causar eso un error en la pool?" Esa es una de las principales razones por la que la
clase String es marcada como final, nadie puede sobrescribir el comportamiento de ninguno de
los mtodos de String, as que puedes estar tranquilo que los objetos inmutables, sern,
inmutables.
Veamos un par de ejemplos de cmo se puede crear un String, y asumamos que no existen
ms objetos en la pool:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 147
En este caso, "abc" ira a la pool y s lo referenciara.

En este caso, ya que usamos new, Java crear una nueva cadena en la memoria normal (no en
la pool), y s la referenciar. Adems, "abc" ira a la pool.

13.1.2 Mtodos importantes de la clase String
Los siguientes mtodos son algunos de los ms comunes usados en la clase String:
charAt() Devuelve el carcter localizado en el ndice especificado.
concat() Concatena una cadena con el final de la otra (lo mismo que "a"+"b").
equalIgnoreCase() Determina la igualdad de dos cadenas ignorando las maysculas.
length() Devuelve el nmero de caracteres en una cadena.
replace() Reemplaza las concurrencias de un carcter con otro carcter.
substring() Devuelve una parte de la cadena.
toLowerCase() Devuelve una cadena con los caracteres en minsculas.
toString() Devuelve el valor en forma de cadena.
toUpperCase() El opuesto a toLowerCase().
trim() Elimina los espacios de una cadena.
Veremos los metodos en detalle.

public char charAt(int index)
Este mtodo devuelve el carcter localizado en el ndice especificado. Recuerda, el primer
ndice es el cero.


public String concat(String s)
Este mtodo devuelve una cadena con el valor del parmetro aadido al final de la cadena.


Los operadores + y += funcionan de forma similar:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 148


En el ejemplo "atlantic ocean", tienes que darte cuenta del valor de x, ha cambiado.
Recuerda que la operacin += es de asignacin, as que realmente est creando la nueva
cadena "Atlantic ocean" y asignndole la variable x, quedando "Atlantic" abandonada.

public boolean equalsIgnoreCase(String s)
Este mtodo devuelve un valor booleano (true o false) dependiendo de si el valor de la cadena
es igual al del mtodo. Este mtodo devolver true aunque los caracteres sean capitales.
Ejemplo:


public int length()
Este mtodo devuelve la longitud de la cadena usada para invocar el mtodo, ejemplo:


public String replace(char old, char new)
Este mtodo devuelve una cadena cuyo valor es la cadena invocada en el mtodo actualizando
la concurrencia. Donde el primer carcter ser reemplazado por el segundo:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 149
public String substring(int begin)
public String substring(int begin, int end)
Este mtodo devuelve una parte de la cadena suministrada. El primer argumento representa la
localizacin (la primera letra ocupa el ndice cero) de la subcadena. Si la llamada tiene solo un
argumento, la subcadena se extraer hasta el final de la cadena original. Si tiene dos
argumentos, la subcadena terminara en el carcter localizado en esa posicin.

Ejemplo:



public String toLowerCase()
Este mtodo devuelve una cadena cuyo valor es la cadena usada para invocar el mtodo, pero
con todas las letras maysculas convertidas a minsculas. Por ejemplo:


public String toString()
Este mtodo devuelve el valor de la cadena usada para invocar el mtodo.
Qu? Para que iba yo a necesitar tal cosa?
Un mtodo que no hace nada? Todos los objetos en Java tienen un mtodo toString(), que
devuelve una cadena significativa que describe el objeto en cuestin. En caso de una cadena,
que ms significativo podra ser que el mismo valor de la cadena? Para ms inri, un ejemplo:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 150
public String toUpperCase()
Este mtodo devuelve una cadena cuyo valor es la cadena usada para invocar al mtodo, pero
todos los caracteres en minsculas los devuelve en maysculas. Por ejemplo:


public String trim()
Este mtodo devuelve una cadena cuyo valor es la cadena usada para invocar el mtodo, pero
los espacios en blanco son eliminados. Ejemplo:




13.2 StringBuffer y StringBuilder
Las clases java.lang.StringBuffer y java.lang.StringBuilder se usan cuando tienes que hacer un
montn de modificaciones a una cadena de caracteres. Tal como vimos antes, las cadenas son
objetos inmutables, si eliges hacer un montn de manipulaciones con objetos de cadena,
terminars con un montn de objetos perdidos en la pool de String. (Incluso en estos das de
los gigabytes de RAM, no es buena idea desperdiciar la memoria en objetos descartados). Por
otra parte, los objetos del tipo StringBuffer y StringBuilder pueden ser modificado tantas veces
como quieras sin dejar por detrs ese rastro de objetos descartados.
StringBuffer vs StringBuilder
La clase StringBuilder fue aadida en Java 5. Tiene el mismo API que StringBuffer, excepto
que StringBuilder no es un hilo seguro. En otras palabras, sus mtodos no estn sincronizados.
Sun recomienda que uses StringBuilder en lugar de StringBuffer cuando sea posible
porque StringBuilder se ejecuta ms rpido. As que aparte de la sincronizacin, cualquier cosa
que digamos sobre los mtodos de StringBuilder valdr para StringBuffer y viceversa.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 151
El uso de StringBuilder y StringBuffer
Hemos visto que en el examen se te va a evaluar la compresin sobre la inmutabilidad de
String en fragmentos como este:

Conseguimos una nueva cadena, pero en trasfondo, la cadena "abc" ha quedado perdida en la
pool de String, malgastando memoria. Si hubiera usado un StringBuffer en lugar de String,
seria:

Todos los mtodos de StringBuffer que discutiremos operan sobre el valor
de StringBuffer invocado del mtodo. As que una llamada a sb.append("def"); est aadiendo
"def" a si mismo. En efecto, estos mtodos pueden ser encadenados unos con otros:

Date cuenta que en los dos ejemplos anteriores, haba solo una llamada a new, y en cada
ejemplo no se han creado objetos extras. Cada ejemplo necesitaba solo una lnea StringXxx
para ejecutarse.

13.2.1 Mtodos importantes de las clases StringBuffer y StringBuilder
Los siguientes mtodos devuelven un objeto StringXxx con el valor del argumento aadido al
valor del objeto que invoca el mtodo.






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 152
public synchronized StringBuffer append(String s)
Como vimos antes, este mtodo actualizar el valor del objeto que invoc el mtodo,
dependiendo de si se le asigna una variable al retorno. Este mtodo toma muchos argumentos,
incluyendo boolean, char, float, int, long y otros.


public StringBuilder delete(int start, int end)
Este mtodo devuelve un objeto StringBuilder y actualiza el valor del objeto StringBuilder que
invoc la llamada al mtodo. En ambos casos, se elimina una subcadena del objeto original. El
ndice inicial (el primero es el cero) se define en el primer argumento y el ndice final (el
primero tiene que ser al menos el 1!) es definido en el segundo argumento. Estudia
detenidamente este ejemplo:


public StringBuilder insert(int offset, String s)
Este mtodo devuelve un objeto StringBuilder y actualiza el valor del objeto que invoc la
llamada del mtodo. En ambos casos, la cadena pasada en el segundo argumento se inserta
dentro del original StringBuilder comenzando en la localizacin offset representado en el
primer argumento (el primero es el cero). Tambin, como segundo argumento puede tomar
cualquier tipo de dato, boolean, char, double, float, int, long...etc... pero es el tipo cadena lo
que ms vas a ver:







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 153
public synchronized StringBuffer reverse()
Este mtodo devuelve un objeto StringBuffer y actualiza el valor del objeto que invoc la
llamada del mtodo. En ambos casos, la cadena en StringBuffer es invertida, el primer carcter
se convierte en el ltimo:


public String toString()
Este mtodo devuelve el valor del objeto StringBuffer que invoco al mtodo como una cadena:

Esto es todo para StringBuffer y StringBuilder. Recuerda que al contrario de los objetos String,
StringBuffer y StringBuilder si mutan.







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 154
14.1 Resumen de las clases I/O

File
Este API dice que la clase File es una representacin abstracta de un fichero y el
nombre de su ruta. La clase File no se usa para leer o escribir datos, se usa para
trabajar a alto nivel, creando ficheros vacos, buscando ficheros, borrando, creando
directorios y trabajando con rutas.
FileReader
Esta clase se usa para leer caracteres de un fichero. El mtodo read() es de bajo nivel, y
te permite leer un solo carcter, de toda la cadena de caracteres, o un nmero fijo de
caracteres. Los FileReader se usan para envolver objetos de alto nivel,
como BufferedReader, que dan ms rendimiento y proveen de formas ms
convenientes para trabajar con datos.
BufferedReader
Esta clase se usa para crear clases Reader de bajo nivel como FileReader, ms
eficientes y fciles de usar. Comparado a los FileReader, BufferedReader es capaz de
leer grandes cantidades de datos de una sola vez y ocuparlos en un buffer. Cuando te
preguntes por el siguiente carcter o lnea de datos, se toma desde el buffer, que
minimiza el nmero de veces de operaciones de lectura. Adems, BufferedReader te
provee de ms eficientes mtodos tales como readLine(), que te permiten leer la
siguiente lnea de caracteres de un fichero.
FileWritter
Esta clase se usa para escribir caracteres a un fichero. Su mtodo write() te permite
escribir caracteres o cadenas a un fichero. Los FileWriter son, normalmente,
envoltorios para objetos de alto nivel de tipo Writer, tales
como BufferedWriter o PrintWriter, que proveen de mejor rendimiento y son de alto
nivel, con mtodo ms flexibles para escribir datos.
BufferedWriter
Esta clase se usa para crear clases de bajo nivel como FileWriter, mas eficiente y fcil
de usar. Comparado a FileWriter, BufferedWriter escriben grandes cantidades de
datos en un fichero de una sola vez, minimizando el nmero de veces, que retrasa, las
operaciones de escritura. Adems, la clase BufferedWriter provee del
mtodo newLine() que hace ms fcil crear plataformas especficas que separan las
lneas automticamente.
PrintWriter
Esta clase ha sido mejorada significativamente en Java 5. Ya que los nuevos mtodo y
constructores creados (como PrintWriter con File o String), puedes encontrar que
puedes usar PrintWriter en sitios donde antes necesitaras un Writer envuelto
con FileWriter y/o un BufferedWriter. Nuevos mtodo
como format(), printf() y append() hacen de PrintWriter una clase muy flexible y
poderosa.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 155
14.2 Creando ficheros, el uso de la clase File
Los objetos del tipo File se usan para representar el fichero actual (pero no los datos que
contiene) o directorios que existen en el disco fsico de la computadora. Comencemos con
unos pocos ejemplos de creacin de ficheros, escribirlos y leerlos. Primero, crearemos un
fichero y escribiremos unas lneas en el:

Si ejecutas este programa, cuando mires el contenido de tu directorio actual, descubrirs que
no hay absolutamente ninguna indicacin de algn fichero llamado fileWrite1.txt. Cuando
creas una instancia de File, no estas creando el fichero, slo el nombre. Una vez que tengas el
objeto File, hay varias maneras para crear el fichero. Veamos lo que puede hacerse con el
objeto File:


Esto da como salida:

false
true
true

Y tambin produce un fichero vaco en tu directorio. Si ejecutas el cdigo una segunda vez, se
mostrar:

true
false
true







Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 156
Examinemos las ejecuciones:
Primera ejecucin:
La primera llamada a exists() devuelve false, lo que esperbamos, recuerda, que new
File() no crea un fichero en el disco! El mtodo createNewFile() crea el fichero, y
devuelve true, indicando que ha sido creado un nuevo fichero, y que no exista antes.
Finalmente, llamamos a exists() otra vez, y esta vez devuelve true, indicando que el
fichero ya existe en el disco.

Segunda ejecucin:
La primera llamada a exists() devuelve true porque nosotros hemos creado el fichero en la
primera ejecucin. Luego la llamada a createNewFile() devuelve false ya que el mtodo no
cre el fichero esta vez. Naturalmente la ltima llamada a exists() devuelve true.
Un par de cosas nuevas han pasado en este cdigo. Lo primero, fjate que tuvimos que poner
nuestro fichero en un try-catch. Esto es as para todos los cdigos I/O que escribes. I/O es una
de esas clases con riesgos inherentes. Seamos simples por ahora, e ignoremos las excepciones,
pero aun necesitaremos seguir manejando o declarando la regla para la mayora de los mtodo
I/O que declaren excepciones marcadas. Hablaremos ms sobre I/O. Usamos un par de
mtodo de la clase File en este cdigo:
boolean exists(), este mtodo devuelve true si puede encontrar el fichero.
boolean createNewFile(), este mtodo crea un nuevo fichero si no existe an.

14.3 El uso de FileWriter y FileReader
En la prctica, lo ms probable es que no uses FileWriter y FileReader sin envoltorio (en breve
se explica mas). Como dije antes, vayamos y hagamos un pequeo fichero I/O:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 157

lo que produce la salida:
12 howdy
folks
Lo que ha pasado:
FileWriter fw = new FileWriter(file) hizo estas tres cosas:
1. Se cre una variable de referencia fw de tipo FileWriter.
2. Se cre un objeto FileWriter y se asign a fw.
3. Se cre un fichero vaco en el disco (puedes comprobarlo).

Escribimos 12 caracteres en el fichero con write(), y luego hizimos flush() y close().

Hicimos un objeto FileReader, que abri el fichero para lectura.

El metodo read() ley todo el fichero, un carcter cada vez, y ponerlo dentro de char[].

Imprimimos el nmero de caracteres ledos, e hicimos un bucle en el array para
imprimir cada carcter, luego, cerramos el fichero.
Antes de seguir, hablemos sobre flush() y close(). Cuando escribes un dato en una cadena,
pueden ocurrir un montn de cosas en el bfer, y nunca sabrs exactamente cundo se envi
el ltimo dato.
Podras ejecutar muchas operaciones de escritura en una cadena antes de cerrarla. Al invocar
el mtodo flush() antes de cerrar el fichero, te garantiza que el ltimo dato se ha escrito en el
fichero.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 158
No importa cmo ests usando un fichero. Para lectura o escritura, tienes que invocar el
mtodo close(). Cuando ests trabajando con ficheros I/O, ests usando una gran cantidad de
recursos del sistema, as que cerrar el fichero liberar las tareas del sistema.
Por mi cuenta he practicado un poco lo dicho aqu, porque no soy persona de estudiar de
memoria, sino de comprender y asociar, y sin estudiar, continuar el temario es como leer y
tener la cabeza ocupada en coches y motos, terminas el libro y no te has enterado de nada, as
que all voy.
Para empezar, acabo de acordarme, que sino inicializas el array, arroja
un NullPointerException. Pensaba que se inicializara como lo hace PHP, automticamente
dependiendo de la entrada. Pues no. Confirmado.
Luego, qu ocurre si declaras un array de 50 bytes y solo ocupas una parte? Bien, este fue el
cdigo que hice:


y este fue el resultado:



Podras haber querido experimentar y darte cuenta que al usar read() sin variable, el cdigo no
lanza error, pero, sin una variable que haga referencia al contenido ledo, como lograras tener
acceso a esta informacin, donde est, quien lo sabe?




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 159
Ahora, volviendo a nuestro ltimo ejemplo del manual. Este programa en realidad, funciona,
pero hay un par de cosas dolorosas:
1. Cuando ests escribiendo datos a un fichero, insertamos manualmente los operadores
de salto de carro (en nuestro caso \n).

2. Cuando leemos los datos, los ponemos en un array. Al estar en un array, tuvimos que
declarar su tamao por adelantado, as que tendramos un problema si no supiramos
el tamao. Podimos leer los datos de carcter en carcter, buscando el final despus
de cada read(), pero es bastante doloroso tambin.
Por estas limitaciones, nosotros usamos clases de ms alto nivel,
como BufferedWriter o BufferedReader en combinacin con FileWriter o FileReader.

14.4 Combinando clases I/O, BufferedWriter y BufferedReader
Todo el sistema I/O de Java fue diseado con la idea de usar varias clases en combinacin.
Combinar las clases I/O se le llama envolviendo clases y otras veces, encadenando clases. El
paquete I/O de Java tiene ms o menos 50 clases,10 interfaces, y 10 excepciones. Cada clase
en el paquete tiene un propsito especfico (creando una alta cohesin) y estn diseadas para
ser combinadas unas con otras de incontables maneras para manejar una amplia variedad de
situaciones. Cuando llega la hora de hacer algo con I/O en la vida real, sin duda te encontrars
con la duda de que API usar o que clases vas a necesitar y como ponerlas juntas.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 160

Ahora, digamos que queremos encontrar una manera menos dolorosa de escribir datos en el
fichero y leer el contenido del fichero a la memoria. Empezando por la tarea de escribir datos
en un fichero, hay un proceso para determinar que clase necesitaremos, y como juntarlas:
1. Ya sabemos que vamos a usar un objeto File. As que si usamos una u otra clase, una
de ellas tiene que llevar un constructor que tome un objeto de tipo File.

2. Encontrar un mtodo que suene como el ms poderoso, el ms fcil de usar para hacer
la tarea. Cuando miramos la tabla, podemos ver que BufferedWriter tiene el
mtodo newLine(). Suena algo mejor que tener que hacer un separador a mano en
cada lnea, pero ms abajo vemos que PrintWriter tiene un mtodo llamado println().
Parece que esto es lo que ms se aproxima de todo lo que tenemos. Vamos con el.

3. Cuando miramos los constructores de PrintWriter, vemos que puede construir un
objeto PrintWriter si tenemos un objeto de tipo File, as que todo lo que necesitamos
hacer es crear un objeto PrintWriter, tal como se muestra:


Hora de un poco de historia. Antes de Java 5, PrintWriter no tena constructores que
tomaran String o File. Si estuvieras escribiendo algo de I/O en Java 1.4, como haras para
conseguir que PrintWriter escribiera datos en File? Puedes imaginrtelo estudiando la tabla.
Aqu hay una manera de resolver este puzle. Primero, sabemos que crearemos un objeto File al
final, y que queremos un objeto PrintWriter. Podemos ver en la tabla que PrintWriter puede
tambin construirse usando un objeto Writer. Aunque Writer no es una clase tal como vemos
en la tabla, vemos que varias clases heredan Writer, lo que se supone como bueno, cualquier
clase que herede Writer es un buen candidato. Mirando ms adelante, vemos que FileWriter
tiene dos atributos que estamos buscando:
1. En el constructor se usa un File
2. Hereda Writer
Dada esta informacin, podemos poner junto el siguiente cdigo (recuerda que es un ejemplo
de Java 4):


Hasta aqu se ve que es fcil encadenar las clases para leer los datos del fichero a la memoria.
Nuevamente, vemos que en la tabla, vemos una tabla que se llama readLine() que suena
mucho mejor para leer datos. Podemos hacer el mismo proceso con el siguiente cdigo:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 161




14.5 Ficheros y directorios
Antes vimos que la clase File se usa para crear ficheros y directorios. Adems, los mtodo de
File pueden ser usados para borrar ficheros, renombrar ficheros y determinar si un fichero
existe, crear ficheros temporales, cambiar los atributos de un fichero y hacer diferencias entre
fichero y directorio. Un punto en el que a menudo se confunde es que un objeto de tipo File se
usa para representar un fichero o un directorio. Hablaremos de ambos en breve.
Como vimos antes, el estamento:

siempre va a crear un objeto File, y luego pueden pasar una de estas cosas:
1. Si "foo" no existe, no se crea ningun fichero.
2. Si "foo" existe, el nuevo objeto File apuntara al fichero existente.
Hay que fijarse que File file = new File("foo"); NUNCA crea un fichero.
Hay dos maneras de crear un fichero:
Invocar al mtodo createNewFile(), por ejemplo:

Crear un objeto Stream, Reader o Writer. Concretamente, un FileReader,
un FileWriter, un PrintWriter, un FileInputStream o un FileOutputStream. Si creas una
instancia de alguna de estas clases, estas creando un fichero, a menos que ya exista,
por ejemplo:






Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 162
Crear un directorio es similar a crear un fichero. Al igual que un fichero, crear un directorio es
un proceso de dos pasos, primero creamos el directorio (usando File), luego creamos un
directorio usando el mtodo mkdir().

Una vez que tienes el directorio, pones ficheros dentro, y trabajas con esos ficheros:



Este cdigo crea un fichero en el directorio. Ya que le suministras el directorio al constructor,
lo que queda es el objeto File. En este caso existe una manera de escribir datos a myFile:



Ten cuidado al crear nuevos directorios! Tal como hemos visto, un Reader o un Writer crearn
tu fichero automticamente si no existe, pero no es el caso de un directorio:



Esto generar una excepcin:
java.io.IOException: No such file or directory
Puedes referirte a un objeto File existente, ya sea fichero o directorio. Por ejemplo, asumamos
que ya tenemos un subdirectorio llamado existingDir en la cual existe existingDirFile.txt, que
contiene varias lneas de texto. Cuando ejecutas este cdigo:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 163
generar la siguiente salida:
true
true
existing sub-dir data
line 2 of text
line 3 of text
Presta especial atencin a lo que devuelve el mtodo readLine(). Cuando no hay ms lneas, el
mtodo devuelve null, que es nuestra seal para parar la lectura del fichero. Tambin, no se ha
invocado el mtodo flush(). Cuando se lee un fichero, no se requiere, as que no vas a
encontrar un flush() en una clase de lectura (Reader).
Adems de crear ficheros, la clase File te permite renombrar y borrar ficheros. El siguiente
cdigo muestra una de las cosas ms comunes como el borrar y renombrar archivos:

da como salida:
delDir is false
y te deja un directorio llamado newDir que contiene un fichero llamado newName.txt. Aqu
hay algunas reglas que podemos deducir del resultado:
delete() Puedes borrar un directorio si est vaco.
renameTo() Le tienes que pasar un objeto File vlido con el nuevo nombre que quieres
(Si newName ha sido null, podra dar un NPE). Tambin puedes cambiar el nombre de
un directorio, aunque no est vaco.
Hay un montn ms para aprender en el paquete IO de Java, pero nos vamos a detener en
una cosa ms, y es como buscar un fichero. Se asume que tenemos un directorio
llamado searchThis que queremos buscar, el cdigo usa File.list() para crear un array de tipo
String de ficheros y directorios, luego usaremos el for mejorado para recorrer el array e
imprimir:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 164

Y conseguimos la siguiente salida:
found dir1
found dir2
found dir3
found file1.txt
found file2.txt
En esta seccin hemos araado la superficie de lo que hay disponible en el paquete IO de Java.
Se podra escribir un libro entero hablando de este paquete, as que obviamente hemos
cubierto una muy pequea parte (pero usada frecuentemente) del API.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 165
15 Paquete I/O, la serializacin
Imagina que quieres guardar el estado de uno o ms objetos. Si Java no tuviese serializacin
(como vimos, en la 1.4 no lo tiene), tendras que usar una de las clases I/O para escribir el
estado de las variables de instancia de todos los objetos que quieres guardar.
La peor parte podra ser la reconstruccin de los objetos que fueron virtualmente creados,
idnticos a los que intentas guardar. Necesitaras tu propio protocolo para crear la manera en
la que habra que escribir y recuperar el estado de cada objeto, o terminaras inicializando las
variables con valores equivocados. Por ejemplo, imagina que guardaste un objeto que tiene
variables de instancia para la altura y el peso. A la vez que grabas el estado del objeto, podras
escribir la altura y el peso como dos int en un fichero, pero el orden es crucial. Sera demasiado
fcil recrear el objeto sin equivocar la posicin de los valores.
La serializacin te permite decir "graba este objeto y todas sus variables de instancia". Es un
poco ms interesante que eso, porque puedes aadir,... a menos que hayas marcado variables
explcitamente como transient, lo que da a entender que no se incluir el valor de esa variable
como parte del estado del objeto serializado.

15.1 ObjectOutputStream y ObjectInputStream
La magia de la serializacin consiste en slo dos mtodos: uno para serializar objetos y
escribirlos es un stream, y el otro para leer el stream y deserializar el objeto.

Estas clases son consideradas de alto nivel, y como vimos antes, significa que tendrs que
envolverlas en clases de bajo nivel, al igual que las clases
java.io.FileOutputStream y java.io.FileInputStream.
Aqu se muestra un pequeo programa que crea un gato (Cat) que lo serializa, y deserializa.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 166
Examinemos los puntos claves de este ejemplo:
Declaramos que la clase Cat implementa la interfaz Serializable. Serializable es una
interfaz marcada, no tiene mtodos que implementar (En las siguientes secciones
cubriremos las reglas que hablan sobre declarar clases Serializable).

Creamos un nuevo objeto Cat, que ya sabemos que es serializable.

Serializamos el objeto Cat c invocando el mtodo writeObject(). Esto tom cierto
trabajo antes de que serializramos nuestro Cat. Primero, tuvimos que poner todo el
cdigo entre try-catch. Luego habamos creado un objeto para escribir
FileOutputStream. Despus envolvimos el FileOutputStream en un
ObjectOutputStream, que es la clase que tiene el mtodo mgico de serializacin que
necesitamos. Recuerda que la invocacin de writeObject() tiene dos tareas, serializa el
objeto y luego lo escribe en un fichero.

Luego deserializamos el objeto invocando readObject(). El mtodo devuelve un objeto,
as que tenemos que castearlo para volverlo Cat. De nuevo, tuvimos que hacer las
acciones tpicas que requiere el I/O cuando trabajamos con el.
Este ejemplo de serializacin ha sido a palo seco. Luego veremos casos ms complejos
asociados a la serializacin.
Por cuenta propia quera saber si era posible guardar ms de un objeto a la vez, intente hacer
un array para guardar todos los objetos del mismo tipo pero no me sali.
Sin embargo, este ejercicio me sirvi para saber tambin, que puedes guardar ms de un
objeto a la vez y recuperarlos usando la operacin inversa. Es decir, guardo dos objetos Gato, y
los leo de una sola vez, asignndole una variable de referencia a cada Gato guardado.

Miremos el ejercicio:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 167

La otra clase:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 168

Interesante, no es cierto? El resultado, por supuesto es correcto:
Gatos guardados :)
Recuperando los gatos...
Tenemos a Miguel y a Juan, gatos Blanco y Marron respectivamente.





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 169
15.2 Objetos grficos
Que quiere decir realmente guardar un objeto?
Si las variables de instancia son todas de tipo primitivo, es bastante directo.
Pero qu pasa si las variables de instancia son en si mismas referencias a objetos?
Que estamos grabando?
Claramente, en Java no tendra sentido grabar los valores actuales de la variable de referencia
porque el valor de la referencia tiene solo el contexto de la instancia de la JVM. En otras
palabras, intentaras recuperar el objeto en otra instancia de la JVM, que aunque este
corriendo en la misma maquina donde el objeto fue serializado, la referencia seria intil.
Que le ocurre al objeto de la variable de referencia que tiene asignada? Miremos esta clase:

Ahora crearemos un perro con un collar, primero, el collar del perro con un tamao:


luego el perro, y le pasamos un collar y la talla de para el perro:


Ahora que pasa si guardas al perro? Si la finalidad es grabar y recuperar un perro, y el perro
recuperado es una duplica exacta del perro que fue guardado, entonces el perro necesita un
collar que sea idntico. Esto significa que el collar del perro debera haberse guardado
tambin.
Y qu ocurre si el collar en si mismo tambin hace referencia a otro objeto? Como el color?
Esto se complica rpidamente. Si dependiera del programador saber cmo est estructurado
cada objeto que se est refiriendo al perro, tendra que guardar el estado de todos los
objetos... que faena. Podra ser una pesadilla con el ms simple de los objetos.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 170
Afortunadamente, el mecanismo de serializacin de Java toma esto en cuenta. Cuando
serializas un objeto, la serializacin toma el objeto completo de forma grfica. Esto significa
que hace una copia muy profunda de todos los objetos que son necesarios recuperar.
Por ejemplo, si serializas un perro, el collar ser serializado automticamente. Y si el collar
hiciera referencia a otro objeto, seria serializado tambin, y as hasta finalizar, siempre que no
olvides aadir la interfaz serializable a las dems clases que incluyas en Dog. Y el nico objeto
del que tienes que preocuparte es de guardar y leer al perro. Los otros objetos requeridos para
reconstruir al perro son guardados y recuperados automticamente a travs de la serializacin.
Recuerda que tienes que ser consciente de crear objetos serializable implementando la
interfaz Serializable. Si queremos guardar al perro, tendremos que modificar la clase como
sigue:


Si ahora guardamos al perro con el siguiente cdigo:



Cuando ejecutamos el cdigo, tenemos una excepcin como esta:
java.io.NotSerializableException: Collar
De que nos hemos olvidado? La clase collar tiene que ser Serializable tambin, si modificamos
la clase collar y la hacemos serializable, no habr problema:









Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 171
Aqu est la lista completa:



Lo que produce:

before: collar size is 3
after: collar size is 3
Y que pasara si no tuviramos acceso al cdigo fuente del collar? En otras palabras, que pasa
si hacer el collar serializable no es una opcin? Obviamente podramos crear una subclase
collar serializable y luego usar la subclase en lugar del collar. Pero eso no es siempre una
opcin por varias razones poderosas:
1. El collar podra ser una clase final
2. El collar podra referirse a otro objeto no serializable, y sin conocer la estructura
interna, no podras hacer los arreglos necesarios.
3. Hacer subclases no es una opcin por razones de diseo.
As que, qu pasa si queremos guardar al perro? Aqu es donde viene el modificador transient.
Si marcas la variable de instancia con transient, la serializacin saltara el collar.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 172


Ahora tenemos un perro serializable, con un collar no serializable, pero el perro tiene el collar
como transient, la salida es:
before: collar size is 3
Exception in thread "main" java.lang.NullPointerException
Y ahora qu hacemos??


15.3 El uso de writeObject y readObject
Considera el problema, tenemos un perro que queremos grabar. El perro tiene un collar y el
collar debera de ser grabado como parte del perro, pero este collar no es serializable, as que
tuvimos que marcarlo como transient. Esto significa que cuando el perro se deserialice, el
collar viene null. Que podemos hacer para asegurarnos de que cuando el perro se deserialice,
tenga un collar que encaje con el mismo collar que tena el perro cuando fue grabado?
Java tiene un mecanismo especial para este caso, un serie de mtodos privados que puedes
implementar en tu clase que, si estn presentes, sern invocados automticamente durante la
serializacin y la serializacin. Es casi como si los mtodos fueran definidos en la
interfaz Serializable, solo que no lo estn. Forman parte de un contrato con el sistema de
serializacin que bsicamente dice "Si tu (el programador) tienes un par de mtodos que
encajen con esta firma exacta (lo veremos en un momento) estos mtodos sern invocados
durante la serializacin y la serializacin".
Estos mtodos te permiten un paso intermedio en la serializacin y la serializacin. Son
perfectos para el problema del collar del perro. Cuando el perro est siendo grabado, puedes
entrar a mitad del proceso y decir "de cualquier manera, me gustara aadir el estado del
collar (un int) al stream cuando el perro sea serializado". Manualmente has aadido el estado
del collar del perro aunque el collar como tal, no se ha grabado.
Naturalmente necesitaras recuperar el collar durante la deserializacin accediendo en ese
paso intermedio y diciendo "Leer un int extra que guard en el stream del perro, y lo usar
para crear un collar nuevo, y luego asignare el nuevo collar al perro que est siendo
deserializado". Los dos mtodos especiales que defines deben ser firmas que son exactamente
como esta:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 173


Si, vamos a escribir mtodos que tienen el mismo nombre como los del ejemplo. Donde se
colocan estos mtodos? Hagamos un cambio en la clase Dog (perro):



Echemos un vistazo al cdigo.
En nuestro escenario hemos concretado que, por alguna razn real, no podamos serializar el
collar pero, queramos serializar el perro (Dog). Para hacer esto, vamos a implementar dos
mtodos, writeObject() y readObject(). Al implementar estos mtodos, le estas diciendo al
compilador "Si alguien invoca writeObject() o readObject() para el objeto Dog, este cdigo
tiene que ser parte de la lectura y la escritura".
1. Como la mayora de mtodos I/O, writeObject() puede arrojar excepciones. Tienes
que declararlas o manejarlas, aunque recomendamos que las manejes.
2. Cuando invocas defaultWriteObject() desde el mtodo writeObject(), le estas diciendo
a la JVM que haga una serializacin normal para este objeto. Cuando
implementas writeObject(), normalmente estas pidiendo un proceso de serializacin
normal, y adems algunos procesos personalizados de escritura y lectura.
3. En este caso hemos decidido escribir un extra int (el tamao del collar) al stream que
se est creando para serializar al perro. Puedes escribir tu cdigo extra antes y/o




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 174
despus de invocar defaultWriteObject(). Pero... cuando lo lees para recuperarlo,
tienes que leerlo en el mismo orden que lo grabaste.
4. De nuevo, elegimos manejar y declarar ms excepciones.
5. Cuando toca deserializar, defaultReadObject() maneja la deserializacin normal que
conseguiras sino implementases readObject().
6. Finalmente construimos un collar nuevo para el perro usando la talla que habamos
serializado manualmente. (Tuvimos que invocar readInt() despus
de defaultReadObject(), si no, los datos del stream saldran desincronizados!)
Recuerda, la mayora de las razones para implementar writeObject() y readObject() son
cuando tienes que grabar alguna parte de un objeto de forma manual. Si lo haces, cuando
quieras hacer solo una parte de la serializacin/deserializacin t mismo, tienes que
invocar defaultReadObject() y defaultWriteObject().
Lo que trae otra pregunta, por qu no se pueden serializar todas las clases de Java? Por qu no
es Object serializable? Hay muchas cosas en Java que no pueden ser serializadas porque estn
en un entorno de ejecucin especfico. Cosas como streams, threads, runtime, etc. y algunas
clases GUI (las cuales estn conectadas al sistema operativo) no pueden serializarse. Lo que es
y no es serializable en Java no tienes que dominarlo, pero necesitars tenerlo en cuenta si
quieres serializar objetos complejos.

15.4 La herencia y la serializacin
La serializacin es algo sensacional, pero para aplicarla efectivamente tienes que entender
como la superclase afecta a la serializacin.

Esto nos trae otro tema clave con la serializacin... qu pasa si una superclase no est marcada
como Serializable pero su subclase lo est? Puede la subclase ser serializada aunque su
superclase no lo sea? Imagnate lo siguiente:


Ahora t tienes la clase perro serializable, con una superclase no serializable. Esto funciona!
Pero hay importantes implicaciones. Para entender estas implicaciones, miremos la diferencias
entre un objeto que viene de una serializacin, y otro que se ha creado con new. Recuerda,
cuando un objeto se construye con new (lo opuesto a uno de una serializacin), ocurren estos
hechos en este orden:
1. Todas las variables de instancia son iniciadas con el valor por defecto.
2. El constructor es invocado, lo cual implica que se invoca el constructor de la superclase
(u otro constructor sobrecargado, hasta que se invoque el constructor de la
superclase.)
3. Todos los constructores de la superclase se completan.




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 175
4. Las variables de instancia inicializadas como parte de su declaracin se les asigna su
valor inicial (lo contrario a los valores por defecto, son valores dados a priori por los
constructores de la superclase.)
5. El constructor finaliza.
Pero nada de esto ocurre en un objeto deserializado. Cuando una instancia de una clase
serializada se deserializa, el constructor no se ejecuta, y las variables de instancia no se les
asigna ningn valor inicial! Piensa en ello, si el constructor fuese invocado, o las variables de
instancia se le asignasen los valores iniciales, el objeto que intentas recuperar en el estado que
lo grabaste, volvera totalmente alterado. Por ejemplo, imagina que tienes una clase que
declara una variable de instancia y le asigna el valor int 3, y le incluyes un mtodo que le
cambia el valor a 10:

Obviamente, si serializas Foo despus de que el mtodo changeNum() se ejecute, el valor de la
variable nim seria 10. Cuando la instancia Foo se deserializa, t quieres que la variable
mantenga su valor de 10! Obviamente no quieres que se inicialice (en este caso, con el 3).
Piensa en el constructor y la asignacin a la variable de instancia como una parte completada
de la inicializacin del objeto (y el hecho, es que ellos hacen la inicializacin en el bytecode). El
punto es, que cuando un objeto se deserializa no queremos que se ejecute la inicializacin. No
queremos que el constructor se ejecute, y no queremos explcitamente valores declarados.
Slo queremos los valores con los que fue grabado.
Naturalmente si tienes variables marcadas como transient, no sern recuperadas con su valor
original (a menos que implementes defaultReadObject()), pero en su lugar, se le darn los
valores por defecto para el tipo de dato. En otras palabras, aunque digas:

cuando la instancia de Bar se deserialice, la variable x tendr el valor cero. Los objetos de
referencia marcados como transient siempre se resetearan a null, no importa si fueron
inicializados en tiempo de declaracin de la clase.
As, que esto es lo que ocurre cuando el objeto se deserializa, y la clase serializada
directamente hereda Object, o tiene solo clases serializables en su rbol de herencia. Tiene
algo de trampa cuando la clase serializable tiene una o ms clases no serializables en su
superclase. Volviendo a nuestra clase Animal con un Dog serializable:




Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 176

Ya que Animal no es serializable, cualquier estado mantenido en Animal, incluso la variable
que se hereda en Dog, no va a ser recuperada cuando se deserialice! La razn es, que la clase
Animal (no serializable) que es parte de Dog va a ser reiniciada igual que si estuvieras
haciendo un nuevo Dog. En otras palabras, las variables de instancia de Dog sern serializadas
y deserializadas correctamente, pero las variables heredadas de Animal sern iniciadas con sus
valores por defecto.
Si tienes una clase serializable pero tu superclase no lo es, entonces cualquier variable de
instancia que heredes de la superclase reseteara sus valores a los suyos por defecto. Esto es
porque el constructor de la superclase se ejecutar!
De hecho, cada constructor encima de la clase no serializable tambin se ejecutar, no
importa, porque una vez que el primer superconstructor sea invocado, su curso invocar sus
superconstructores hasta el principio del rbol de herencia.
Necesitars tambin reconocer que variables sern recuperadas y cules no, as que asegrate
de estudiar el siguiente ejemplo y la salida:





Curso gratuito de Java en emuladores L2 Java
2012
e m a i l : b r u j u l a t o @y a h o o . e s

Pgina 177
Da como resultado:
before: Fido 35
after: Fido 42
La clave aqu es Animal, que no es serializable, cuando el Dog fue deserializado, el constructor
de Animal se ejecut y reseteo la variable weight.

15.5 Serializacin y clases estticas
Finalmente, te has podido dar cuenta que hemos hablado solo de variables de instancia, no de
variables estticas. Las variables estticas deberan ser grabadas aparte del estado del objeto?
No es importante que la variable esttica sea serializada con el objeto? Si y no. Puede ser
importante pero no es una parte del estado de la instancia. Recuerda, que debes pensar que
las variables estticas son puramente variables de clase. Ellas no tienen nada que ver con las
instancias individuales. Pero la serializacin se aplica solo a los objetos. Y que sucede si
deserializa tres instancias distintas de Dog, que fueron serializados a distinta vez, y que todos
fueron grabados con una variable esttica en la clase con un valor distinto? Que instancia
debera prevalecer? Qu valor esttico debera ser usado para reemplazar el actual en cada
clase Dog que est cargado actualmente? Ves el problema?
Las variables estticas nunca se graban como parte del estado del objeto, porque no
pertenecen al objeto!

Potrebbero piacerti anche