Vous êtes sur la page 1sur 25

OTRO CURSO EN: http://www.webtaller.

com/manual-
java/indice_manual_java.php

El Proceso de Abstracción , Lenguajes Computacionales y Objetos.

Todo lenguaje de programación ofrece un proceso de abstracción sobre un concepto


extraído del mundo real, en otras palabras, un lenguaje permite un mapeo entre un
problema espacial(real) hacia uno maquinal que será aquel ejecutado por una
computadora. Es en esta capacidad de abstracción es que reside la facilidad/complejidad
de generar programas funcionales capaces de resolver el problema espacial.

El lenguaje ensamblador es una abstracción de la maquina ejecutora ("procesador");


lenguajes como Fortran, Basic y C son abstracciones de este mismo lenguaje
ensamblador, sin embargo, aunque estos últimos ofrecen un avance sobre el lenguaje
ensamblador, estos aún requieren de procesos de abstracción considerables.

Lo anterior produce programas que son difíciles de escribir y actualizar por la simple
razón que el problema espacial dista en grandes proporciones del mapeo maquinal;
frente a estas deficiencias han surgido lenguajes más apegados al problema real tales
como: PROLOG donde todo problema es mapeado a una cadena de decisiones o LISP
donde todo problema es convertido a listas.

Aquí es donde los lenguajes orientados a objetos salen a relucir, esto se debe a que
permiten llevar acabo un mapeo más directo con el problema espacial(real). Allan Kay,
describió las 5 principales características de Smalltalk, uno de los primeros lenguajes
orientados a objetos y uno de los lenguajes en los cuales esta basado Java:

• Todo es un objeto: Considere un objeto una variable especial, no solamente


guarda datos, sino también se pueden hacer solicitudes a este Objeto en sí. En
teoría, cualquier elemento en el problema espacial(real) (edificios, servicios,
automóviles, u otra entidad) puede ser representado como un objeto en un
programa.
• Un programa es un conjunto de Objetos, enviándose mensajes entre sí : Para
realizar una solicitud a un Objeto es necesario enviarle un mensaje.
Concretamente se puede pensar que un mensaje es una solicitud para llamar una
función que pertenece a cierto objeto.
• Cada Objeto tiene su memoria, conformada por otros Objetos : En otras
palabras, es posible generar un tipo de Objeto nuevo agrupando Objetos
existentes. De esta manera se pueden armar estructuras complejas en un
programa, escondidas detrás de la simplicidad de Objetos.
• Todo Objeto tiene su Tipo: En este sentido Tipo se refiere a Clase, donde cada
Objeto es una instancia de una Clase en cuestión.La característica más
importante de una Clase es el tipo de mensajes que pueden ser enviados a ella.
• Todo Objeto de un mismo tipo puede recibir los mismos mensajes : Esto
implica que si un Objeto es del tipo Circulo, un Objeto del tipo Figura será
capaz de recibir mensajes de Circulo, puesto que un Circulo es una Figura. Este
concepto forma parte medular de todo lenguaje orientado a Objetos y será
explorado en una sección especifica de este curso.
En la gráfica anterior se puede observar una Clase conformada por una Lampara
(problema espacial real) a la cual pueden ser enviados distintos mensajes tales como:
prender, apagar, girar y cambiar; para crear un Objeto de esta Clase y ser
utilizado dentro de un programa es necesario generar una instancia del mismo, esto se
demuestra a continuación:

Lampara candil = new Lampara();


candil.prender();

El primer renglón genera una instancia de la Clase Lampara la cual es asignada a la


referencia candil; en la segunda linea, a través de esta referencia se manda llamar el
método prender() definido en la misma Clase; a través de referencias es posible
generar distintos Objetos del mismo tipo cada uno con su propio comportamiento:

Lampara candil = new Lampara();


Lampara manual = new Lampara();
Lampara jardin = new Lampara();
candil.prender();
candil.girar();
manual.apagar();
jardin.prender();
jardin.elevar();
candil.apagar();

Lo anterior demuestra una de las principales características de los lenguajes orientados a


Objetos, sin embargo, a continuación se describen las características especificas del
Lenguaje Java y porque es considerado uno de los más avanzados en su ramo.

Java y sus Características

Entre los lenguajes orientados a Objetos hoy en día Java figura entre los más utilizados
comparado con sus homólogos, pre-aparición de Java el lenguaje C++ se encontraba en
la cúspide para desarrollos de Software con orientación a Objetos, sin embargo, Java ha
venido suplantando su uso debido a dos características muy especificas que C++ no
ofrece.

Interoperabilidad de Plataforma

Esta característica forma parte del lema Java: "Write once, run everywhere" (Escribalo
una vez, ejecutelo en todos lados), a continuación se ilustra este concepto.
El proceso de creación es muy similar a la de otros lenguajes: una vez creado el Código
Fuente es necesario compilarlo para generar un binario, este binario denominado Byte-
Code en Java lleva por extensión .class, sin embargo, a diferencia de otros lenguajes
este binario (Byte-Code) puede ser ejecutado en diversas plataformas obteniéndose el
mismo resultado final.Esta interoperabilidad de ejecución se debe a que el Byte-Code es
ejecutado en una maquina virtual llamada "Java Virtual Machine", es a través de este
componente que se logra una ejecución idéntica en distintos ambientes.

Hoy en día, existen diversos JVM("Java Virtual Machines") para distintas plataformas y
ambientes que oscilan desde los Sistemas Operativos Linux,Solaris,Windows,HP-UX
hasta productos como Bases de Datos Oracle y Servidores de Aplicaciones BEA; esto
permite que código escrito en Java pueda ser ejecutado en cualquier ambiente
produciéndose los mismos resultados.

Recolección de Basura ("Garbage Collection")

En la sección anterior se pudo observar como son generadas distintas instancias de


Objetos a través de una referencia, sin embargo, el uso de esta metodología trae
consigo otro pregunta : Que se hace con estas instancias una vez que ya no son
utilizadas ? La importancia de este concepto se debe al uso de memoria en una
computadora, es lógico que estas instancias de Objetos requieren memoria ("RAM")
para mantener su información, ahora bien, también tiene sentido asumir que la memoria
("RAM") es limitada en todo sistema, esto trae consigo el problema denominado "fuga
de memoria" ("memory leak").

Si alguna vez ha programado en el lenguaje C++ debe estar familiarizado con este
concepto, el cual significa que los recursos de memoria ("RAM") han sido agotados en
el sistema. Suponga que ha diseñado un programa que invoca la creación de miles de
instancias , eventualmente su memoria ("RAM") puede fugarse si no ha tomado las
precauciones necesarias para deshacerse/destruir estas instancias de Objetos.

En el mundo Java, esta administración explicita de instancias de Objetos no es


necesaria debido al proceso de "Garbage Collection"; este mecanismo a través del JVM
("Java Virtual Machine") inspecciona constantemente la memoria empleada por Java, lo
cual le permite ir eliminando las instancias de Objetos que han dejado de ser utilizadas
en un programa, en el proceso despreocupándose de la destrucción de Objetos.

Aunque el concepto de recolección de basura ("Garbage Collection") posee una


infinidad de detalles en su fondo, es conveniente saber que este proceso es llevado
automáticamente por Java, y que es una facilidad no ofrecida en otros lenguajes como
C++

JDK/J2SE.

JDK ("Java Development Kit") y J2SE ("Java 2 Standard Edition") son nombres para el
mismo componente utilizado en ambientes Java, el cual agrupa las diversas
funcionalidades necesarias para desarrollar programas Java.

Hoy en día, existen JDK's/J2SE para diversos ambientes y plataformas, los cuales
ofrecen lo siguiente:

• Un compilador Java, capaz de generar Byte-Code.


• Un JVM ("Java Virtual Machine"), capaz de ejecutar Byte-Code.
• Un conjunto de Clases base utilizadas para generar programas Java.
• Otras utilerías para administrar código escrito en Java.

Para este curso se hace uso del JDK/J2SE de Sun Microsystems , aunque claro esta,
cualquier programa generado en este JDK puede ser ejecutado otros ambientes, al igual
que programas compilados en otros JDK's/J2SE pueden ser ejecutados en este ambiente.
El conjunto de Clases base proporcionadas por el JDK/J2SE incluyen clases de uso
común tales como : Manipulación de String's, Fechas y Números así como todas las
funcionalidades base esperadas de un lenguaje computacional como: Ordenamiento y
manipulación de Arreglos, Operaciones matemáticas complejas (Trigonométricas y
Exponenciales) y escritura/lectura de "Streams".

Además de estas Clases base, el JDK/J2SE posee otra serie de Clases especializadas
que también ofrecen la base para la creación de otros componentes Java que incluyen :
Applets, Objetos CORBA , Fragmentos Auditivos, Soporte de Criptografía (Seguridad)
y Manipulación de XML entre otras funcionalidades.

Aunado a las Clases base, el JDK/J2SE incluye una serie de ejecutables utilizados para
diversas tareas como : Creación de ejecutables (Byte-Code), generación de
documentación, creación de "Stubs" y "Skeletons" a través de IDL e inclusive una
implementación de un ORB ("Object Request Broker") para interactuar con ambientes
CORBA, entre otros ejecutables.

La estructura de directorios del JDK/J2SE es la siguiente:

JDK 1.4.2
___________|_________________
| | |
bin lib jre
| | ________|__________
java* tools.jar | |
javac* dt.jar bin lib
javap* | ________ ___|___ _________ ________
_______
javah* java* | | | | |
|
javadoc* rt.jar ext security i386 applet
fonts
charsets.jar | / \
| / \
localedata.jar server client

Como se puede observar, la estructura se encuentra dividida en tres grandes partes :

• bin: Incluye los ejecutables para la generación de programas Java.


• lib: Contiene las librerías (Clases) base empleadas en la generación de la gran
mayoría de programas Java.
• jre: Incluye el ambiente necesario para ejecutar programas Java, el cual a su vez
se encuentra sub-dividido en distintos directorios.

Dependiendo de la manera en que haya instalado la


documentación del JDK, se recomienda observarla en estos
momentos para que se familiarice con sus Clases Base.

Un Programa Java.

Para entrar en materia es necesario escribir nuestro primer programa Java, el cual ilustra
la sintaxis así como estructura de un programa básico.

• Programa Java Introducción .

Librerías ("Packages") y JAR's.

Conforme empieza a crecer un desarrollo de Software surge la necesidad de reutilizar


ciertos componentes que ya han sido escritos, así como dar cierta estructura para
mantener una organización de código; al igual que otros lenguajes, esta organización se
lleva acabo mediante librerías, denominadas "packages" en el mundo Java .

Java toma una perspectiva nueva respecto a otros lenguajes, adoptando una convención
a partir de Dominios en Internet, esto es, nuestros programas y por ende librerías
("packages") estarán basados en el nombre de la empresa/dominio para la cual son
diseñados, lo anterior permite evitar la tan conocida Colisión de Nombres en Software.

Esta Colisión de Nombres se da cuando dos Clases llevan el mismo nombre y ambas
requieren ser utilizadas dentro de un programa en particular, empleando Dominios en
Internet se garantiza que el nombre de la Clase/Librería sea única , puesto que es una
característica de Dominios en Internet.

Para que puedan ser asignadas Clases a determinadas librerías es necesario indicar dicha
Librería("Package") en la definición inicial de un programa, además de esto, es
necesario crear una estructura de directorios para generar las determinadas Clases; lo
anterior se ilustra mejor a través de un ejemplo:

• Generación de Librerías ("Packages") .


• Utilización de Librerías ("Packages") .

Una vez acumuladas un número substancial de Clases en una Librería("Package") será


necesario colocarlas en una estructura que permita una distribución fácil y práctica, esto
es, si ha generado 100 o 500 clases sería muy impráctico distribuir la estructura de
directorios a un tercero para ser utilizada, para este problema han sido diseñados los
archivos JAR ("Java Archives").

• Generación de Archivos JAR ("Java Archives") .

La Variable CLASSPATH.

Al utilizar Clases y Librerías en ambientes Java surge otro tema en lo que concierne a
su ubicación: Cuales Clases/Librerías están disponibles al momento de
Compilar/Ejecutar programas Java ? , la respuesta a esta pregunta es la conocida
variable CLASSPATH.

A través de esta variable se indica donde residen las Clases/Librerías("Packages") de


nuestro ambiente, en ella se definen los directorios base de Clases así como cualquier
archivo JAR que requiera ser cargado al compilar/ejecutar programas Java.

Para definir/alterar esta variable existen dos alternativas: Definirse al nivel de Sistema
en variables de ambientales o al tiempo de invocarse un comando Java, ya sea java o
javac.

• Utilización de la Variable CLASSPATH .

Calificadores: Public, Private, Protected, Static y Final.

El uso de calificadores de acceso en Java tiene sus bases en el uso de librerías


("packages"), al ser diseñado un programa existen diversas funciones/métodos y
variables dentro de éste, algunas de estas requerirán ser modificadas conforme
incrementen las necesidades del programa, mientras otras permanecerán inmóviles, la
importancia de estos cambios requiere que sean utilizados calificadores para
permitir/negar el acceso a ciertos segmentos del programa, analicemos el siguiente caso:

Usted ya diseño 300 clases que están siendo re-utilizadas por otros programas, sin
embargo, se le ha solicitado una modificación radical a estos objetos base, cuales
métodos/campos de estas 300 Clases puede modificar sin quebrantar los otros
programas que hacen uso de estas ? Aquí puede surgir un serio problema sino han sido
utilizados los calificadores de acceso acordemente.

Ahora bien, además de los calificadores de acceso que permiten restringir el uso de
métodos/campos a determinadas situaciones, también existen otros calificadores que
afectan directamente la creación y uso de instancias por clase estos calificadores son
static yfinal.
public : Acceso libre .

El uso del calificador public significa que toda definición será accesible de cualquier
punto, ya sea un método, campo o clase. Su uso implica un acceso global, desde luego
el uso de este calificativo en Clases que serán modificadas constantmente es
fuertemente desalentado, ya que puede quebrantar dependencias forjadas en versiones
previas.

private : Solo en la misma Clase .

El calificador private indica que dicho componente será accesible únicamente dentro
de la Clase en cuestión, si se intenta accesar cualquier elemento de este tipo dentro de
otra Clase será generado un error de compilación.

El calificador private suele utilizarse en Clases que serán modificadas continuamente,


esto permite evitar futuros quebrantos en otras Clases como fue mencionado al inicio.

protected : Clases Heredadas y misma Clase.

El uso de protected es utilizado bajo los conceptos de Herencias ("Inheritance"), aunque


este tema será descrito en otra sección, mediante protected es posible accesar elementos
de la Clase Hereditaria ("Inherited"), aunque no aquellos que utilicen el calificador
private.

En otras palabras, si determinada Clase hijo hereda ("inherit") el comportamiento de


una Clase padre, la Clase hijo tendrá acceso a todos aquellos campos/métodos definidos
como protected en padre, pero no aquellos declarados como private en padre.

Ningún Calificador : Clase en Librería y misma Clase .

Finalmente, cuando no es empleado ninguno de los calificadores de acceso


mencionados anteriormente los elementos son considerados amigables, esto implica que
todo campo/método carente de calificador será accesible dentro de todas Clases
pertenecientes a su misma librería("package").

static : Una sola instancia .

El uso del vocablo static ha venido siendo utilizado en los métodos principales (main)
de los programas escritos anteriormente, su uso esta relacionado directamente al uso de
instancias en Clases; en ocasiones es necesario o conveniente generar elementos que
tomen un mismo valor para cualquier número de instancias generadas o bien
invocar/llamar métodos sin la necesidad de generar instancias, y es bajo estas dos
circunstancias que es empleado el calificador static.

El primer uso de static puede ser poco evidente, pero tomemos el caso de la Clase
mencionada al inicio de este curso de una Lampara, en caso de requerirse un elemento
como un apagador pudiera resultar sobrado generar una instancia para cada Lampara,
en este caso pudiera ser restringido un apagador a una sola instancia mediante el
calificador static permitiendo que dicho elemento sea utilizado por todas las
instancias de Lampara ahí generadas; desde luego la descripción anterior esta
trivializada, sin embargo, conforme se avance en el presente curso serán ilustrados otros
ejemplos con este mecanismo.

La segunda situación para el uso de static puede ser ejemplificada


perfectamente a través del método main Java, el método main puede ser llamado
automáticamente al invocarse la respectiva Clase debido a que no se encuentra asociado
con ningún tipo de instancia, esto implica que su comportamiento siempre será el
mismo independientemente de la instancia que realza su llamada.

Dos aspectos característicos de utilizar el calificador static en un elemento Java son


los siguientes :

• No puede ser generada ninguna instancia (Uso de new) de un elemento static


puesto que solo existe una instancia.
• Todos los elementos definidos dentro de una estructura static deben ser
static ellos mismos , o bien, poseer una instancia ya definida para poder ser
invocados.
• NOTA: Lo anterior no implica que no puedan ser generadas instancias dentro de
un elemento static; no es lo mismo llamar/invocar que crear/generar.

La teoría del concepto static puede ser un poco difícil de digerir, sin embargo, como
fue mencionado anteriormente, conforme avance el curso serán descritos diversos
fragmentos de código para dejar en claro su uso.

final : Una sola instancia y definitiva.

El calificador final estrechamente relacionado con el uso de static implica una


asignación única y definitiva al elemento de una clase. A diferencia de static que
implica una sola instancia, el termino final lleva dicha instancia a una definición única
y como su nombre lo implica final.

Generalmente final es utilizado en aquellos elementos que no serán modificados al


momento de ejecutarse ("Run-Time") un programa o clase , a través de final se asigna
un valor que no podrá ser modificado bajo ninguna circunstancia al momento de
ejecución ("Run-Time), en efecto logrando un nivel de eficiencia en ejecución.

De igual manera que la utilización de static el uso de final será ilustrado conforme
se avanze en este curso.

Objetos y Primitivos.

Al diseñar sus primeros programas en Java, pudo notar que todo gira alrededor de
instancias de Objetos que son manipuladas a través de referencias:

Lampara candil = new Lampara();


candil.prender();

Al utilizar referencias en Java estas pueden ser inicializadas sin que pertenezcan a
ninguna instancia de Objeto:
String let;

La declaración anterior genera una referencia, sin embargo, esta no es asociada con
ninguna instancia de Objeto, para llevar acabo este proceso es necesario utilizar el
vocablo new.

String let = new String("Algo sencillo")

La declaración anterior no solo genera una instancia nueva de la Clase String, sino le
asigna un valor inicial ("Algo sencillo") el cual es asignado a la referencia let; este
mecanismo de agregar valores al generar una instancia es llevada acabo a través de
métodos denominados constructores los cuales serán descritos posteriormente.

El hecho de generar instancias de objetos es un proceso involucrado ( hablando en


términos computacionales mas no en sintaxis ) , es por esto que Java ofrece un
mecanismo simplístico para definir estructuras de datos como alternativa a utilizar
Clases/Objetos, dichas estructuras son conocidas como primitivos.

Aunque estrictamente hablando un primitivo no es una clase a través de un primitivo se


facilita el uso de valores comúnmente utilizados en lenguajes de programación, donde el
generar una instancia de Clase resultaría en un proceso tardado y mecánico. En la
siguiente tabla se describen los diversos primitivos disponibles en el lenguaje Java:

Tipo de Valor Valor Valor


Tamaño "Wrapper"
Primitivo Mínimo Máximo Default
boolean - - - false Boolean
Unicode 216- `\u0000'
char 16-bit Unicode 0 Character
1 (null)
byte 8-bit -128 +127 (byte) 0 Byte
short 16-bit -215 +215-1 (short) 0 Short
int 32-bit -231 31
+2 -1 0 Integer
long 64-bit -263 63
+2 -1 0L Long
float 32-bit IEEE754 IEEE754 0.0f Float
double 64-bit IEEE754 IEEE754 0.0d Double
void - - - - Void

Nótese que estos primitivos inician con letra minúscula, en la tabla anterior se describen
los rangos de dichos primitivos así como sus respectivos "Wrappers"; estos
"Wrappers" son Clases utilizadas como contra parte de primitivos:

char c = 'x';
Character C = new Character(c);

La primer linea genera un primitivo el cual es asignado a la variable c, posteriormente


se genera una instancia de la Clase Character (Nótese el uso del vocablo new); el uso
de "Wrappers" (Objetos) para primitivos es empleado bajo ciertas circunstancias, sin
embargo, vale mencionar que existen diversos mecanismos para convertir de Clases tipo
Objeto ("Wrappers") a primitivos y viceversa, a continuación se describen los
mecanismos para realizar este tipo de conversiones :

• Uso de "Wrappers" y primitivos en Java .

El uso práctico para emplear "Wrappers" y/o primitivos será explorado en una futura
sección de este curso.

Campos("Fields") y Métodos.

Cuando se define una Clase esta puede contener dos tipos de elementos: Campos
("Fields") o Métodos, los métodos ya fueron descritos en los ejemplos anteriores, sin
embargo , un campo es un objeto o primitivo utilizado para guardar datos en cada
instancia de un objeto :

• Uso de Campos("Fields") en Java .

En Java existen ciertos campos que son definidos como final, y aunque dicho
calificativo puede ser empleado en métodos y Clases su uso más común es en campos,
su significado puede ser descrito con las siguientes palabras: "No puede cambiar"; las
razones por las que es utilizado final pueden ser: Eficiencia o Diseño.

Al utilizarse final en variables (primitivos) estas toman un valor constante al llevarse


acabo la compilación, lo anterior permite mayor eficiencia al momento de ejecutarse un
programa ("Run-Time"), ahora bien, cuando es utilizado final en referencias de Objetos
se restringe que dicha referencia sea utilizada para apuntar hacia otro Objeto, esto
permite realizar un diseño que prohibe a la referencia ser re-asignada, el uso del vocablo
final será explorado en otra sección de este curso.

En ciertos métodos es utilizado el vocablo return que permite indicar el valor de


retorno para un método:

• Uso de return en Métodos .

Constructores.

Un Constructor es un método especial en Java empleado para inicializar valores en


Instancias de Objetos, a través de este tipo de métodos es posible generar diversos tipos
de instancias para la Clase en cuestión; la principal característica de este tipo de
métodos es que llevan el mismo nombre de la clase, a continuación se describen varios
ejemplos utilizando constructores:

• Utilización de Constructores .

Métodos y Parámetros por Referencia.

Cuando son utilizados Constructores puede surgir la necesidad de inicializar algún


campo perteneciente a la Clase, esto trae consigo otro detalle en lo que concierne la
asignación de valores dentro de un método, la razón se debe a que dentro de un método
puede surgir el requerimiento de accesar campos definidos en la Clase, observe:
public Class Cableado {
int longitud;
String tipo;

public Cableado(String tipo, int longitud) {


this.tipo = tipo
this.longitud = longitud;
}
....
....
}

En el caso anterior, dentro del constructor se desea asignar valores a los campos de una
Clase, sin embargo, dentro del constructor son utilizados como parámetros de entrada
los mismos valores, para tener acceso a los campos de la Clase se utiliza el vocablo:
this, al emplear esta sintaxis se esta haciendo alusión a los campos de la Clase.

Aunque sería posible emplear distintos nombres para los valores de entrada, evitando el
uso del vocablo this, la sintaxis con el vocablo this es ampliamente utilizada en el
caso de Constructores mencionado anteriormente, así como Java Beans, un concepto
utilizado en Java para ambientes Web (JSP's/Servlets).

Generación de Documentación (Vía Comentarios)

En muchos lenguajes el mantener documentación acerca de las Clases/Métodos escritos


es una tarea que requiere un esfuerzo adicional, ya que por una parte debe mantenerse el
código funcional mientras se debe generar documentación acerca de la funciones; en
muchas ocasiones esta documentación ni existe, en Java la generación de
Documentación es llevada en conjunción del código a través de comentarios.

A través de comentarios colocados en cada Clase/Método es posible generar


documentación de una manera inmediata y concisa en formato de documentos HTML /
XHTML , a continuación se describe un ejemplo :

• Utilización de Comentarios .
• Generación de Documentación .

Herencias ("Inheritance")

Uno de las partes medulares en un lenguaje orientado a Objetos es el uso de Herencias


("Inheritance") , el cual permite reutilizar Clases existentes con todas las
funcionalidades/comportamientos ya diseñadas en ellas; en Herencias ("Inheritance") el
termino reutilizable toma otro sentido al utilizado en la secciones anteriores al
importarse Clases (import), uno más complejo y poderoso, observe:
El primer diagrama UML ("Universal Markup Language") muestra 3
Clases(Guitarra,Piano,Saxofón) que heredan ("Inherit") de una Clase Base
(Instrumento),mientras el segundo diagrama muestra 2 Clases (Circulo,Triangulo) que
heredan ("Inherit") de una Clase Base (Figura); este mecanismo permite que nuevas
Clases hereden el comportamiento de una Clase Base ya depurada y funcional, en el
proceso teniendo acceso a los métodos/campos ya creados con anterioridad ; a
continuación se describe un ejemplo que hace uso de Herencias ("Inheritance"):

• Uso de Herencias ("Inheritance") .

El uso de Herencias es ampliamente utilizado en diseños Java, inclusive las Clases Base
del JDK lo utilizan extensamente, si observa la documentación de estas Clases, notará
en la parte superior el árbol de Herencias ("Inheritance") para la Clase correspondiente,
donde todas son descendientes de la Clase Base java.lang.Object.

Condicionales if/else.

En Java al igual que otros lenguajes son utilizados condicionales que


permiten controlar el flujo de ejecución en un programa, los tres principales tipos son el
conocido if/else,while y for; a continuación se describen varios ejemplos con el uso de
if/else:

• Utilización de Condicional if/else .

Uso de los Ciclos for y while

El uso de Ciclos en lenguajes de programación es un concepto ampliamente utilizado, a


continuación se describe el uso del ciclo for y while :

• Ciclo for en Java .


• Utilización de Condicional while .
En ciertas ocasiones surge la necesidad de interrumpir un ciclo si ocurre determinada
condición, o bien, saltar una iteración en ciertas circunstancias, este comportamiento se
logra a través de los vocablos break y continue, a continuación se describe su uso:

• break/continue en Ciclos .

Otra variación para interrumpir y saltar iteraciones en ciclos es a través de Etiquetas


(Labels), este mecanismo logra un comportamiento similar al famoso, pero criticado
"goto". Aunque su uso es permitido, es fuertemente desalentado debido a la poca
legibilidad que resulta en el código.

• Etiquetas Labels en Ciclos.

Uso de switch.

A través de un Switch se posible definir una serie de tareas cada una


asignada a una lista de valores, este tipo de estructura es ideal cuando se requieren
condicionales que lleven más de dos valores, en lugar de anidar grupos de condicionales
if/else es posible lograr el mismo comportamiento a través de un switch:

• Utilización de Switch.

Operadores Matemáticos, Relacionales y Lógicos.

En Java al igual que otros lenguajes existen diversos operadores que son empleados en
diferentes secciones de un programa, a lo largo de los distintos programas escritos en
este Curso se han empleado su gran mayoría, sin embargo, en esta sección se
describirán detalles más precisos acerca de su funcionamiento.

Antes de entrar en el uso de Operadores, a continuación se describe un ejemplo que


demuestra el comportamiento de Asignación de valores para el lenguaje Java:

• Asignación de Valores.

Operadores Relacionales.

A través de operadores relacionales es posible llevar acabo un proceso de comparación


entre dos elementos en un programa, siendo su característica principal el generar un
resultado verdadero o falso; dichos operadores relacionales se muestran a continuación :

Operador Significado
< Menor que
> Mayor que
<= Menor que o Igual
>= Mayor que o Igual
== Igual
!= No Igual
Muchos de estos Operadores han sido utilizados a lo largo de este curso, a continuación
se demuestra un uso muy común de estos operadores:

• Utilizando Equivalencias.

Operadores Matemáticos.

En Java se encuentran disponibles los mismos operadores matemáticos que en otros


lenguajes, mencionados a continuación :

Operador Significado
+ Suma
- Resta
= Igual
* Multiplicación
/ División
% Modulo (El residuo de una División)

Java también ofrece una sintaxis para llevar acabo una operación matemática y
asignación en una sola simbología, esta es llevada acabo mediante: "+=","-=","*=","/=";
además de esta sintaxis también existen los operadores de auto-incremento y auto-
decremento que son representados por "++" y "--" respectivamente.

En los siguientes ejemplos se describe el uso de los diversos operadores matemáticos:

• Utilización de Operadores Matemáticos.


• Utilización de Operadores Auto-Incremento y Decremento.

Además de estos operadores matemáticos, el lenguaje también posee una Clase estándar
(en el JDK) para realizar operaciones más complejas, esta Clase bajo el nombre de
java.lang.Math ofrece operaciones trigonométricas, exponenciales y otras más; a
continuación se describen algunos ejemplos empleando dicha clase :

• Utilización de métodos en java.lang.Math.

Operadores Lógicos.

Los operadores lógicos para el lenguaje Java son los siguientes:

Operador Significado
|| O (OR)
&& Y (AND)
! Negación (NOT)

A continuación se describe un ejemplo que hace uso de estos operadores :

• Operadores Lógicos en Java.


Definición de Errores y Bloques try/catch/finally.

Aunque el tiempo ideal para encontrar errores es al momento de compilar un programa,


esto no siempre es posible y por esta razón han sido diseñados mecanismos para
encontrarlos al momento de ejecución ("Run-Time").La metodología más común para
trabajar con errores en lenguajes de programación es interrumpir el flujo de ejecución e
invocar otro código que maneje el error en cuestión; en el lenguaje Java a la ocurrencia
de errores se le denomina "Exceptions" y al procesamiento de errores "Trap" (atrapar).

Como habría de esperarse, al encontrarse un error ("Exception") en Java es necesario


invocar una Clase que realiza las respectivas tareas, para mandar llamar este tipo de
Clases es necesario utilizar el vocablo throws; suponiendo que desea atrapar un error si
determinada variable no ha sido inicializada, se utilizaría la siguiente sintaxis:

if(t == null)
throw new NullPointerException();

Al utilizar una definición similar a la anterior, se asume que ya se conoce el tipo de


error que puede ser generado en el programa, sin embargo, este no siempre es el caso y
por esta razón en Java se define una Zona Especifica donde puede ser generado un error
y a su vez atrapado, esta Zona "Protegida" es el conocido bloque try/catch/finally, a
continuación se describe la sintaxis de este bloque:

• Sintaxis del Bloque try/catch/finally.

Además de los errores ("Exceptions") ofrecidos en las Clases Base del JDK, es posible
definir errores propietarios para llevar un control más estricto sobre la generación de
errores:

• Definición y uso de una Clase para Errores ("Exceptions").

Datos de Entrada

A lo largo de los diversos métodos definidos en los distintos programas, se ha podido


observar que estos definen sus Datos de Entrada seguido del nombre del mismo dentro
de un paréntesis (calificadores nombre_del_metodo (datos_de_entrada)).

La sintaxis de los datos de entrada se compone de dos partes: El tipo de Clase/Primitivo,


seguido de la referencia empleada dentro dentro del método; por "default" los métodos
principales (main) en Java deben especificar un Arreglo de String's en su definición,
esto con la intención de recibir parámetros al momento de ser llamada la Clase, a
continuación se describe un ejemplo que hace uso de este mecanismo:

• Utilización de Datos de Entrada .

El uso de Datos de Entrada descrito anteriormente es trivial, ya que es realizado antes de


iniciarse la ejecución de un programa, en la siguiente sección será descrito el uso de
"Streams" para la lectura/escritura de datos en archivos y otros elementos.

"Streams"
Un "Stream" es un nombre genérico otorgado a un flujo de caracteres en un programa
de computo, puede estar compuesto por los valores residentes en un archivo texto, datos
introducidos interactivamente por un usuario o datos que desean ser colocados en
determinado archivo.

Un "Stream" es la representación más cruda de un juego de datos, pero una manera muy
universal de accesar/guardar datos, inclusive la clase System.out.println utilizada en
la gran mayoría de los programas de este curso también es un "Stream"; en Java existen
diversas Clases utilizadas en conjunción de "Streams", a continuación se describen estas
Clases :

• Clases utilizadas en "Streams" .

El uso de "Streams" en programación es un tema muy extenso y en ocasiones


considerado muy abstracto, por esta razón son descritos dos ejemplos en las siguientes
secciones:

• Utilización de un "Stream" para leer Archivos.


• "Stream" para escribir Archivos.

Arreglos.

Un uso muy común en diseños de Software es agrupar distintos valores relacionados


entre sí en una sola variable, lo cual permite una manipulación más eficiente de datos;
en el lenguaje Java existen diversos mecanismos para agrupar datos en conjunto, una de
ellas que ha venido siendo utilizada a lo largo de los distintos programas en este curso
es denominada: Arreglo.

A través de un Arreglo es posible generar agrupaciones de cualquier tipo de Objeto


simplemente agregando una simbología de corchetes , ya sea seguido de la definición de
Clase o bien la referencia en cuestión, a continuación se describen diversos ejemplos
más amplios de Arreglos:

• Utilización de Arreglos .

Al final de esta sección serán descritas otras metodologías para agrupar datos que
poseen distintas ventajas a emplear un Arreglo.

Polimorfismo

El concepto de Polimorfismo es uno de los fundamentos para cualquier lenguaje


orientado a Objetos, las mismas raíces de la palabra pueden ser una fuerte pista de su
significado: Poli = Multiple, morfismo= Formas , esto implica que un mismo
Objeto puede tomar diversas formas.

A través del concepto de Herencias ("Inheritance") es posible ilustrar este


comportamiento:
El poder manipular un Objeto como si éste fuera de un tipo genérico otorga mayor
flexibilidad al momento de programar con Objetos, el término Polimorfismo también es
asociado con un concepto llamado Late-Binding (Ligamiento Tardío), observe el
siguiente fragmento de código:

Figura a = new Circulo();


Figura b = new Triangulo();

Inicialmente se puede pensar que este código generaría un error debido a que el tipo de
referencia es distinta a la instancia del objeto, sin embargo, el fragmento anterior es
correcto y demuestra el concepto de Polimorfismo; para asentar este tema se describe un
ejemplo más completo:

• Uso de Polimorfismo .

El uso de Polimorfismo posee ciertos detalles que no fueron descritos en el ejemplo


anterior, uno de estos, que también tiene implicaciones en otros componentes es:
Casting.

Uso de "Casting"

El termino "Casting" viene de la palabra "Cast" que significa Molde, por lo que el
termino literal es Hacer un Molde, en Polimorfismo se lleva acabo este proceso de
"Casting" implícitamente, una Guitarra se coloca en el molde de un Instrumento, un
Triangulo en el molde de una Figura, sin embargo, en ciertas ocasiones se requiere
realizar un tipo de "Casting" que no es considerado seguro en términos
computacionales.

Anteriormente se mencionó que el "Casting" llevado acabo con Polimorfismo es


implícito, esto se debe a que no se requiere de sintaxis especial, simplemente se
convierte una Guitarra a un Instrumento, sin embargo, para llevar una transformación
en sentido opuesto se requiere de sintaxis adicional para mantener la seguridad de
transformación; analicemos: mientras se puede asegurar que un Triangulo es una
Figura ("Up-Casting"), una Figura no necesariamente es un Triangulo, claro esta que
lo puede ser, pero en Java se requiere definir explícitamente esta operación ("Down-
Casting").

El uso practico de "Down-Casting" será explorado en la sección de Vectores y


"Hashtables".

Interfases y Clases Abstractas.

Clases Abstractas.

Al ser utilizado Herencias ("Inheritance") y/o Polimorfismo es muy común que en la


Clase Base existan métodos diseñados únicamente con el propósito de ofrecer una guia
para las Clases heredadas, en Java existe un vocablo que permite prohibir el uso de
métodos en Clases Base, este calificativo es : abstract.Al ser definido un método como
abstract se restringe que éste sea llamado directamente, cuando una Clase contiene un
método de este tipo a ésta se le llama: Clase Abstracta.

Al ser definida una Clase, además de ser declarados los métodos/campos como abstract
también es necesario utilizar el vocablo abstract en la definición de cada Clase.

• Clases Abstractas .

Una de las características de las Clases que Heredan("Inherit") de una Clase abstracta,
es que éstas deben definir los mismos métodos definidos en la Clase Base; en Java
existe otro mecanismo que permite llevar acabo diseños donde se parte de una
Estructura o Cápsula.

Interfases.

Una Interfase es una Clase abstracta llevada al extremo, la cual permite pre-definir el
uso de métodos/campos en futuras clases tal como: Una jerarquía de Instrumentos
restringido al uso de una Interfase Instrumento, o bien, una estructura de Figuras al uso
de la Interfase Figura.

Una Interfase básicamente dice: "Todas las Clases que implementen esta Interfase deben
contener su misma estructura", para definir una Interfase se utiliza el vocablo
interface y para especificar que una Clase debe utilizar determinada Interfase se
utiliza el vocablo implements.

Al ser utilizada una Interfase en una Clase se esta indicando: "La Interfase dicta la
forma/estructura ahora se va describir como debe funcionar", en el siguiente ejemplo se
describe el uso de Interfases:

• Definición y uso de Interfases. .

Una característica especifica de Interfases que no es posible a través de Clases


Abstractas es el uso de Herencias Múltiples ("Multiple Inheritance"), este concepto
reside en diseñar Clases que adoptan el comportamiento de más de una Clase, a
continuación se describe su uso:
• Herencias Múltiples ("Multiple Inheritance") a través de Interfases. .

Cabe mencionar que el uso de Interfases es ampliamente utilizado en EJB's ("Enterprise


Java Beans") uno de los principales componentes de J2EE ("Java 2 Enterprise Edition").

Vectores, Hashtables y otras estructuras de Datos.

Algunas de las principales características de Arreglos en Java son las siguientes:

• Es necesario definir el tamaño de un Arreglo antes de ser utilizado, este se hace


con la intención de administrar el uso de memoria, pero a su vez presenta la
restricción de utilizar Arreglos en estructuras de datos cambiantes.
• Un arreglo únicamente puede incluir Objetos/primitivos del mismo tipo, si bien
esto permite un control más estricto sobre estructura de datos, restringe una
posible mezcla de elementos comunes que difieran en su Clase.

A diferencia de un Arreglo, un Vector es un tipo de Objeto que permite almacenar


objetos (referencias) de cualquier tipo, que además de ofrecer estas facilidades, también
es posible que su tamaño incremente conforme las necesidades del programa lo
requieran; aparentemente este es un contenedor de Objetos ideal para toda situación, sin
embargo, su uso puede ser un poco deficiente ya que requiere mayor uso de memoria
que un arreglo de Objetos, el siguiente ejemplo demuestra el uso de esta Clase :

• Uso de Vectores .

Otro elemento que es ampliamente empleado en programación es la utilización de listas


de valores con determinados conceptos, esto es conocido como key-value lists y en el
mundo Java recibe el nombre de "Hashtable", a continuación se describe un ejemplo de
"Hashtable's":

• Uso de "Hashtables" .

Además del uso de Vectores y "Hashtables", también existen otra serie de Clases para el
almacenaje de Objetos, cada una de éstas posee sus ventajas y desventajas para agrupar
elementos comunes; mayores detalles sobre estas estructuras de datos serán descritas a
continuación en el "Collection Framework" de Java.

Collections Framework.

Mientras en la sección anterior se describió el uso de estructuras de datos para agrupar


Objetos, tales como Arreglos, Vectores y Hashtables, estas estructuras también
conocidas como Collections fueron incorporadas en las versiones iniciales de Java, sin
embargo, en las distribuciones más recientes de la plataforma (1.2) han sido agregadas
otra serie de estructuras para manipular grupos de Objetos, lo que ha llevado a
conformar un Collections Framework.

A través de un Collection Framework se uniformiza la manera en que son manipulados


grupos de Objetos, donde las características principales de éste Collection Framework
son:
• Interfases : Son definidas una serie de Interfases que permiten extender o
generar Clases especificas para manipular objetos en forma grupal
("Collections").
• Implementaciones : Proporciona una serie de implementaciones (Clases)
concretas en las que se pueden almacenar objetos en forma grupal
("Collections").
• Algoritmos : Ofrece una serie de métodos estándar para manipular los objetos
dentro de una implementación ("Collection"), como ordenamiento o búsqueda.

A continuación se describe la estructura de Interfases definidas en el Collection


Framework:

I. Collection: Esta interfase representa un grupo general de objetos, donde es


posible que el grupo contenga objetos duplicados.
o List: Es un tipo de Collection que permite duplicados, sin embargo,
contiene mecanismos para indexar sus valores, esto permite extraer
elementos en base a su posición (Similar a un Vector).
o Set: También es un tipo de Collection que prohibe el uso de objetos
duplicados.
 SortedSet: Es un tipo de Set que mantiene un orden natural
sobre sus valores, y ofrece una serie de métodos avanzados para
ordenamiento.
II. Map: Permite el almacenamiento de listas de valores (key-value lists) y no puede
contener valores duplicados (key's).
o SortedMap: Es un tipo de Map que mantiene un orden natural sobre sus
valores (key's), y ofrece una serie de métodos avanzados para
ordenamiento.

Es a partir de esta estructura de Interfases que se derivan una serie de implementaciones


proporcionadas en el JDK, a continuación se describen diversos ejemplos que hacen uso
de las Clases proporcionadas en el JDK diseñadas alrededor de las interfases que
forman la parte medular del Collection Framework:

• Utilización de List, Set y SortedSet .


• Utilización de Map y SortedMap .

"Threads"

Los diversos programas que han sido diseñados en este curso poseen una característica
común que consiste en realizar sus tareas de una manera monolítica, sin embargo, en
ciertos diseños surge la necesidad de fragmentar la ejecución de un programa en
diversos sub-procesos o tareas, y es precisamente a través de "Threads" que se logra
este comportamiento .

Un "Thread" permite distribuir el tiempo de ejecución y recursos asignados a


determinados bloques de un programa, aunque abstracto en definición, una vez en
contexto su comprensión es sencilla. La clásica ilustración de "Threads" es en
programas con interfase gráfica, tomemos el caso de un "Browser"(Navegador) escrito
en Java, mientras la ejecución del "Browser" es un programa en sí, dentro de éste se
encuentran diversos "Threads" (Sub-procesos) latentes que nos permiten estar
descargando un archivo o navegando un página simultáneamente, esto es, somos
capaces de realizar varias tareas a pesar que el "Browser" es un programa monolítico.

Existen dos maneras para trabajar con "Threads" en una Clase Java :

• Heredar ("Inherit") de la Clase Thread : Esta Clase proporcionada con el


JDK contiene todos los mecanismos necesarios para crear y ejecutar "Threads".
• Emplear la Interfase Runnable : Esta interfase también proporcionada con el
JDK contiene los métodos necesarios para operar con "Threads", aunque claro
esta, como toda otra interfase deben ser implementados sus métodos.

Los ejemplos descritos a continuación ilustran los conceptos más comunes de "Threads"
en Java :

• Uso de "Threads" con Clase java.lang.Thread .


• Uso de "Threads" con sincronización.

Además del mecanismo empleado en los ejemplos anteriores para utilizar "Threads",
existe otra manera de emplearlos en el lenguaje Java y ésta es a través de la interfase
java.lang.Runnable; observe el siguiente fragmento :

public class Reloj extends Applet implements Runnable {

El fragmento anterior ilustra la declaración inicial de un Applet que hará uso de


"Threads", en este caso resulta necesario heredar ("inherit") el comportamiento de otra
Clase (Applet), por lo que el uso de java.lang.Thread queda restringido al no poder
heredar vía extends más de una Clase.

Lo anterior aplica como regla general en todo uso de "Threads": Mientras no sea
necesario heredar ("inherit") el comportamiento de otra Clase se debe emplear
java.lang.Thread, sin embargo, si se requiere heredar el comportamiento de otra
Clase y tener acceso a "Threads" es necesario emplear la interfase
java.lang.Runnable para garantizar la implementación correcta de un "Thread".

Garbage Collection

El proceso de "Garbage Collection" mencionado en las primeras secciones de este


curso, se refiere a la limpieza de instancias (Objetos) las cuales han dejado de ser
utilizadas en un programa Java. Este proceso llevado acabo directamente por el JVM
("Java Virtual Machine") permite liberar recursos, en su mayoría de memoria ("RAM")
para ser reutilizados por el sistema, sin embargo, este proceso trae consigo dos
preguntas :

Que instancias/objetos son elegidos y liberados por el proceso de "Garbage


Collection" ? : Toda instancia/referencia que sea asignada un valor de null es elegible
para "Garbage Collection", si la instancia/referencia no tiene un valor de null ésta no es
elegible para "Garbage Collection". Ahora bien, nótese el énfasis en elegible, esto
implica que aunque la instancia/referencia sea asignada con un valor de null ésta no
será liberada ("Garbage Collected") inmediatamente, sino hasta que el proceso de
"Garbage Collection" sea iniciado.

Quien invoca el proceso de "Garbage Collection" ? : El JVM ("Java Virtual


Machine") se hace cargo de iniciar el proceso de "Garbage Collection" únicamente
cuando éste (según sus algoritmos internos) determine que su memoria esta en proceso
de agotamiento, es hasta entonces que es liberada la memoria de las
instancias/referencias que se han declarado como elegibles para "Garbage Collection".

System.gc y Runtime.gc

Existe un método llamado gc() dentro de las Clases java.lang.System y


java.lang.Runtime cuyas iniciales significan "Garbage Collection" y puede ser
llamado directamente dentro de un programa Java.

Sin embargo, a pesar de su nombre, el hecho de invocar este método directamente (en
cualquiera de las Clases) no implica que se realice el proceso de "Garbage
Collection" inmediatamente, lo único que logra es expeditar (acelerar) los mecanismos
para iniciar el proceso de "Garbage Collection"; el momento preciso en que es invocado
el proceso de "Garbage Collection" depende del JVM ("Java Virtual Machine"), según
fue descrito anteriormente.

"Assertions"

Un "Assertion" o aseveración es un mecanismo empleado en lenguajes de programación


para garantizar el cumplimiento de ciertas reglas/normas al momento de ejecutarse un
programa. Mientras el proceso de compilación garantiza que la sintaxis escrita en un
programa sea la correcta , el uso de "Assertions" es empleado para garantizar que
determinados datos introducidos al flujo de un programa cumplan con ciertos requisitos.

Ahora bien, aunque también pudieran ser utilizados bloques try/catch para capturar este
tipo de errores, el uso de bloques try/catch implica anticipar un tipo de error (Clase)
además de escribir código extenso, esto a diferencia de una aseveración ("Assertion")
donde es posible definir una condición específica que debe cumplir un programa para
proceder con su ejecución. Los siguientes ejemplos demuestran el uso de este
mecanismo para programas Java

• Uso de aseveraciones ("Assertions") .

En Java, el uso de "Assertions" es una nueva adición a partir del JDK 1.4, por lo que su
uso requiere de ciertas medidas al compilar y ejecutar programas para garantizar
compatibilidad con versiones anteriores. A continuación se describen los diversos pasos
que deben tomarse para activar aseveraciones al momento de compilar y ejecutar un
programa.

• Activación de aseveraciones ("Assertions") .

Palabras Reservadas
En Java al igual que otros lenguajes de computo existen varias palabras que se
encuentran reservadas para uso exclusivo en sus estructuras internas, lo anterior implica
que estos términos no pueden ser utilizados para nombres de campos, métodos, clases u
otras estructuras de datos; la mayoría de estas palabras han sido descritas en el
contenido del presente curso, sin embargo, a continuación se ilustra una tabla concisa
que contiene dichas palabras:

abstract assert boolean break byte case catch

char class const * continue default do double

else extends final finally float for goto *

if implements import instanceof int interface long

native new null package private protected public

return short static strictfp super switch synchronized

this throw throws transient try void volatile

while

* Aunque no utilizada por el lenguaje Java, es palabra reservada.

• goto y const: Son identificadores ampliamente utilizados en C++, en Java se


encuentran restringidas estas palabras para facilitar la detección de errores en
sintaxis de este tipo.
• true, false y null: Aunque aparentemente pudieran ser consideradas palabras
reservadas, éstas representan simplemente literales (valores) boolean's y nulo; lo
anterior es importante únicamente para efectos de exámenes de certificación
Java.

Java 5 / JDK 5 .

La nueva versión de Java -- Java 5 / JDK 5 -- ha incorporado una serie de


funcionalidades y sintaxis que tendrán un efecto directo sobre el tiempo de desarrollo en
aplicaciones de este lenguaje, incrementado así su productividad como desarrollador.

En forma de atajos, mayores salvaguardas para detectar errores, o simplemente en la


simplificación de escribir código, los principales cambios se encuentran enunciados en
las siguientes secciones

Clases genéricas para el "Collections Framework" y Arreglos.

El uso de clases genéricas es una funcionalidad que permite garantizar el tipo de


elementos colocados en una colección Java -- esto es, una de las clases del "Collections
Framework" -- y a su vez evitar el proceso explicito de extracción necesario para
manipular los objetos que en él se contienen.

• Uso de clases genéricas para el "Collections Framework" y Arreglos .

Auto-boxing y auto-unboxing, entre primitivos y objetos.


El uso de auto-boxing y auto-unboxing tiene sus raíces en el uso de primitivos Java. A
pesar que la mayoría de los diseños en Java giran alrededor de manipular objetos, el uso
de primitivos como boolean, char , byte, int , long, float y double
permanecen en amplio uso.

Un caso típico donde son utilizados primitivos es aquel donde se realizan operaciones
matemáticas, esto se debe en parte a la sencillez de generar un primitivo, ya que no
requiere inicialización de objeto mediante new, mismo factor que favorece eficiencia de
ejecución comparado con usar un objeto. Sin embargo, a pesar de las ventajas
presentadas al utilizar primitivos, existen casos -- como el de guardar primitivos en una
colección de objetos -- que requieren conversiones continuas de un primitivo hacia un
objeto y viceversa.

Este tipo de conversiones en versiones previas a Java 5, son realizadas mediante


métodos proporcionados en clases "Wrappers" de cada primitivo, un proceso mecánico
y tedioso, a pesar de ser obvio el comportamiento de conversión deseado. Ante estos
procesos laboriosos de conversión, fueron integrados los mecanismos de auto-boxing y
auto-unboxing para permitir la conversión de valores primitivos hacia sus respectivos
objetos "Wrappers" de manera directa y sin mayores complicaciones.Observemos un
ejemplo.

• Uso de auto-boxing y auto-unboxing, entre primitivos y objetos .

Ciclos de iteración simplificados.

Los ciclos de iteración se encuentran entre las estructuras más comunes en


programación, para Java 5 se ha incorporado una sintaxis nueva para simplificar su uso.

• Ciclos de iteración simplificados .

Anotaciones en código fuente -- meta-datos.

Anotaciones en código fuente es otra de las funcionalidades incorporadas en Java 5. A


través de anotaciones se tiene la posibilidad de utilizar información complementaria
colocada directamente en código fuente -- meta datos -- al momento de compilar o
ejecutar una clase Java.

El mecanismo de colocar información dentro del código fuente para fines distintos al de
ejecución no es algo nuevo para Java, el proceso para generar documentación de clases
emplea este mismo mecanismo y ha estado disponible desde las primeras versiones Java
[ Observe el proceso para generación de documentación en Java], sin embargo, lo que
resulta importante de esta funcionalidad en Java 5 es la capacidad de utilizar dicha
información para fines de indicar instrucciones al compilador o JVM ("Java Virtual
Machine").

• Anotaciones en código fuente -- meta-datos .

Uso de Enumeraciones.
Una enumeración es una estructura de datos diseñada para agrupar información estática
y facilitar su acceso de otras clases. Esta funcionalidad ya presente en una serie de
lenguajes de programación, como C++ y Perl, esta siendo debutada en el mundo Java
hasta esta versión 5.

Como sería normal esperar, ante la falta de apoyo directo en el JDK para
enumeraciones, muchos desarrolladores familiarizados con esta técnica han creado sus
propias maneras de simular el comportamiento. Ahora veamos si usted es uno de éstos,
y de ser así, como incorporar la estructura formal de una enumeración a un programa
Java, o de lo contrario, en que casos resulta apropiado utilizarla.

• Uso de enumeraciones .

Capacidad para importar clases estáticas.

Al hacer uso de librerías en programas Java, el mecanismo para tener acceso a ellas es a
través del vocablo import, esto es, si deseamos hacer uso de las interfases o clases del
"Collections Framework" debemos colocar la declaración : import java.util.* en la
parte superior de la clase.

Aunque este proceso de acceso es estándar para la mayoría de clases Java, en versiones
previas a Java 5 no es posible utilizarlo en un tipo de clase : Clases estáticas. El acceso a
este tipo de clases en versiones del JDK 1.4 y anteriores requiere que éstas mismas sean
declaradas explícitamente dentro del código central del programa. Observemos un
ejemplo.

• Capacidad para importar clases estáticas .