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:
A continuación se describe la estructura de Interfases definidas en el Collection Framework:
Collection
: Esta interfase representa un grupo general de objetos, donde es posible que el grupo contenga objetos duplicados.
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
).
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.
Map
: Permite el almacenamiento de listas de valores (key-value lists) y no puede contener valores duplicados (key's).
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:
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 :
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".
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".
|
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
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.
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.