You are on page 1of 62

Manual de Java + J2EE

Walter Montesano

walter.a.montesano@accenture.com
Manual de Java + J2EE

Java : Introduccin al lenguaje


Historia
Java se remonta al ao 1991, cuando a un team-lider de Sun le ofrecieron un mejor puesto en
otra empresa. El jefe del team-lider le propuso entonces, como contra-oferta, ponerlo a cargo
de un proyecto atractivo: un sistema que controle electrodomsticos ante su aparente
perspectiva de continuo desarrollo. La reducida potencia de clculo y memoria de los
electrodomsticos llev a desarrollar un lenguaje sencillo capaz de generar cdigo de tamao
muy reducido. Debido a la existencia de distintos tipos de CPUs y a los continuos cambios, era
importante conseguir una herramienta independiente del tipo de CPU utilizada. Desarrollaron
un cdigo neutro que no dependa del tipo de electrodomstico, el cual se ejecutaba sobre
una mquina hipottica o virtual denominada Java Virtual Machine (JVM). Era la JVM quien
interpretaba el cdigo neutro convirtindolo a cdigo particular de la CPU utilizada. Esto
permita lo que luego se convertira en el principal lema del lenguaje: Write Once, Run
Everywhere. A pesar de los esfuerzos realizados por sus creadores, ninguna empresa de
electrodomsticos se interes por el nuevo lenguaje.
Como lenguaje de programacin para computadoras, Java se introdujo a finales de 1995. Las
claves fueron la aparicin (y aceptacin) de HotJava y la incorporacin de un intrprete Java
en la versin 2.0 del programa Netscape Navigator, produciendo una verdadera revolucin en
Internet.

El mundo Java
Al programar en Java no se parte de cero. Cualquier aplicacin que se desarrolle se basa en
un gran nmero de clases preexistentes. Algunas de ellas pueden ser creadas por el propio
usuario, otras pueden ser comerciales, pero siempre hay un nmero muy importante de clases
que forman parte del propio lenguaje (el API o Application Programming Interface de Java).
Java incorpora en el propio lenguaje muchos aspectos que en cualquier otro lenguaje son
extensiones propiedad de empresas de software o fabricantes de computadoras (threads,
ejecucin remota, componentes, seguridad, acceso a bases de datos, etc.). Por eso muchos
expertos opinan que Java es el lenguaje ideal para aprender a programar, porque incorpora
todos estos conceptos de un modo estndar, mucho ms sencillo y claro que con las citadas
extensiones de otros lenguajes. Esto es consecuencia de haber sido diseado ms
recientemente y por un nico equipo.
El principal objetivo del lenguaje Java es llegar a ser el nexo universal que conecte a los
usuarios con la informacin, pudiendo sta residir en la computadora local, en un servidor de
Web, en una base de datos o en cualquier otro lugar.
JDK (Java Development Kit) es el entorno de programacin es suministrado por Sun de forma
gratuita, pudindose encontrar en la direccin web: http://Java.sun.com/j2se/.
Es de consenso que el entorno jdk no es el ms adecuado para el desarrollo de aplicaciones
Java, debido a funcionar nica y exclusivamente mediante comandos de consola, ya que hoy
en da la programacin se suele ayudar de entornos visuales, como JBuilder, JCreator, Eclipse,
BlueJ, etc. Sin embargo, puede ser un entorno bastante til para aprender el lenguaje, ya que
aunque los entornos visuales nos hagan mucho trabajo siempre es necesario ir al cdigo para
modificarlo y obtener el comportamiento deseado, lo cual quiere decir que necesitamos
dominar el lenguaje y es ms fcil llegar a este dominio escribiendo cdigos completos en un
entorno hostil que no nos ayuda, que simplemente remodelando cdigos ya generados por
entornos visuales.

Pgina 2 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Finalmente, JRE (Java Runtime Environment) es un conjunto de programas y bibliotecas que
permiten que un programa Java se ejecute en una computadora. O sea, es el paquete que
instala la mquina virtual en una PC.
El JDK y el JRE se sirven de variables de entorno y de parmetros en las llamadas a los
ejecutables, entre las cuales las ms importantes son:

PATH: es la ruta (la ruta es un conjunto de directorios o "carpetas" separados por


punto y coma) donde se encuentran los ejecutables.

CLASSPATH: es la ruta donde se encuentran las clases necesarias para el proyecto.

JAVA_HOME: es la ruta a la raz del JRE. Aunque JBoss busca en esta variable la raz
del JDK.

Caractersticas de Java
La compaa Sun describe el lenguaje Java como simple, orientado a objetos, distribuido,
interpretado, robusto, seguro, de arquitectura neutra, portable, de altas prestaciones,
multitarea y dinmico.
A continuacin, se explicaran algunas de estas caractersticas:
Simple: es un lenguaje sencillo de aprender. Su sintaxis es la de C++ simplificada.
Los creadores de Java partieron de la sintaxis de C++ y trataron de eliminar de este todo lo
que resultase complicado o fuente de errores en este lenguaje.
Orientado a objetos: posiblemente sea el lenguaje ms orientado a objetos de todos
los existentes; en Java todo, a excepcin de los tipos fundamentales de variables (int, char,
long...), es un objeto.
Distribuido: Java est muy orientado al trabajo en red, soportando protocolos como
TCP/IP, UDP, HTTP y FTP. Por otro lado el uso de estos protocolos es bastante sencillo
comparndolo con otros lenguajes que los soportan.
Robusto: el compilador Java detecta muchos errores que otros compiladores solo
detectaran en tiempo de ejecucin o incluso nunca. (ej: if(a=b) then...) el compilador Java no
nos dejara compilar este cdigo.
Seguro: sobre todo en los Applet. Estos son programas diseados para ser ejecutados
en una pgina Web. Java garantiza que ningn Applet puede escribir o leer de nuestro disco o
mandar informacin del usuario que accede a la pgina a travs de la red (como, por ejemplo,
la direccin de correo electrnico). En general no permite realizar cualquier accin que pudiera
daar la mquina o violar la intimidad del que visita la pgina Web.
Portable: en Java no hay aspectos dependientes de la implementacin de los distintos
compiladores, todas las implementaciones de Java siguen los mismos estndares en cuanto a
tamao y almacenamiento de los datos. Esto no ocurre as en C++.
Arquitectura neutral: el cdigo generado por el compilador Java es independiente de la
arquitectura: podra ejecutarse en un entorno UNIX, Mac o Windows. El motivo de esto es que,
el que realmente ejecuta el cdigo generado por el compilador no es el procesador de la
computadora directamente, sino que este se ejecuta mediante una mquina virtual. Esto
permite que los Applets de una Web pueda ejecutarlos cualquier mquina que se conecte a
ella, independientemente de qu sistema operativo emplee (siempre y cuando la computadora
en cuestin tenga instalada una mquina virtual de Java).
Los programas desarrollados en Java presentan diversas ventajas frente a los desarrollados en
otros lenguajes como C/C++. La ejecucin de programas en Java tiene muchas posibilidades:
ejecucin como aplicacin independiente (Stand-alone Application), ejecucin como applet,
ejecucin como servlet, etc. Un applet es una aplicacin especial que se ejecuta dentro de un
navegador o browser (por ejemplo Netscape Navigator o Internet Explorer) al cargar una
pgina HTML desde un servidor Web. El applet se descarga desde el servidor y no requiere
instalacin en la computadora donde se encuentra el navegador. Un servlet es una aplicacin

Pgina 3 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
sin interfaz grfica que se ejecuta en un servidor de Internet. La ejecucin como aplicacin
independiente es anloga a los programas desarrollados con otros lenguajes.
Recolector de basura: El recolector de basura es una caracterstica que permite que
los objetos inicializados, se destruyan automticamente cuando ya no estn referenciados. En
Java no hay que preocuparse por quedarse sin memoria, porque no han sido destruidos los
objetos que ya no estn referenciados. Esto es un problema, por ejemplo en C++, que hay
que destruir manualmente los objetos sin referencias. Java lo hace automticamente.

Palabras reservadas
Existe una serie de palabras reservadas las cuales tienen un significado especial para Java
y por lo tanto no se pueden utilizar como nombres de variables. Dichas palabras son:
abstract

boolean

break

byte

case

catch

char

class

const*

continue

default

do

double

else

extends

final

finally

float

for

goto*

if

implements

import

instanceof

int

interface

long

native

new

null

return

short

package

private

protected

public

static

super

switch

synchronized this

throw

throws

transient

try

void

while

volatile

(*) son palabras reservadas, pero no se utilizan en la actual implementacin del lenguaje
Java.

Variables
Una variable es un nombre que contiene un valor que puede cambiar a lo largo del programa.
De acuerdo con el tipo de informacin que contienen, en Java hay dos tipos principales de
variables:
1. Variables de tipos primitivos. Estn definidas mediante un valor nico que puede ser entero,
de punto flotante, carcter o booleano. Java permite distinta precisin y distintos rangos de
valores para estos tipos de variables (char, byte, short, int, long, float, double, boolean).
2. Variables referencia. Las variables referencia son referencias o nombres de una informacin
ms compleja: arrays u objetos de una determinada clase.
Desde el punto de vista del papel o misin en el programa, las variables pueden ser:
1. Variables miembro de una clase: Se definen en una clase, fuera de cualquier mtodo.
Pueden ser tipos primitivos o referencias.
2. Variables locales: Se definen dentro de un mtodo o, ms en general, dentro de cualquier
bloque entre llaves {}. Se crean en el interior del bloque y se destruyen al finalizar dicho
bloque. Pueden ser tambin tipos primitivos o referencias.
A continuacin se dar una tabla con los distintos tipos de variables y su rango:
TIPO
byte

TAMAO
1 byte

RANGO
Valores numricos de 128 a 127

Pgina 4 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
short
int

2 bytes
4 bytes

long
float
double
char
boolean

8
4
8
2
1

bytes
bytes
bytes
bytes
byte

Valores numricos de 32.768 a 32.767


Valores numricos de 2.147.483.648 a 2147483647
Valores numricos de -9.223.372.036.854.775.808 a
9.223.372.036.854.775.807
Valores numricos hasta 38 cifras
Valores numricos hasta 308 cifras
Valores alfanumricos
Solo admite TRUE o FALSE

Como puede apreciar, no existe en Java un tipo de dato primitivo para cadenas de texto. En
su lugar se utiliza una clase, String. Los objetos de esta clase se manipulan por mtodos, por
ejemplo, para comparar cadenas se utiliza equals o equalsIgnoreCase.
if (txtLoc.equalsIgnoreCase(txtLocSel))
Por otro lado, la concatenacin se realiza directamente con el operador +.
cad = txtLoc + ", ARGENTINA";
Si se concatena una cadena con un nmero, ste se convertira a String previamente.
cad = "GBH " + 5

// cad pasa a valer "GBH 5"

Veremos ms sobre la clase String ms adelante.


Un aspecto a tener en cuenta es que en Java las variables locales no se inicializan a ningn
valor, en tanto que las variables de instancia y las variables miembro de un arreglo, s se
inicializan (a 0 las de tipos enteros, a 0.0 las de coma flotante, a false las booleanas, null
para las variabled de referencia, y a '\0' las que son de tipo char). Si tuviermos un cdigo
como el siguiente
{
int x;
x = x + 1;
...
}
Java no permitira compilar el programa, pues la variable x nunca fue inicializada.
Conversin entre tipos numricos
Las normas de conversin entre tipos numricos son las habituales en un lenguaje de
programacin: si en una operacin se involucran varios datos numricos de distintos tipos
todos ellos se convierten al tipo de dato que permite una mayor precisin y rango de
representacin numrica.
double <- float <- long <- int <- short <- byte
Es posible convertir un dato de jerarqua superior a uno con jerarqua inferior,
arriesgndonos a perder informacin en el cambio. Este tipo de operacin (almacenar el

Pgina 5 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
contenido de una variable de jerarqua superior en una de jerarqua inferior) se denomina
cast.
int i = 9,k;
float j = 47.9F;
k = (int)j; //empleo de un cast

mbito de las variables


ste en Java viene dado por los corchetes: {}; una vez definida una variable en un cdigo
dejar de existir cuando se acabe el bloque de cdigo en el que se defini. Los bloques de
cdigo empiezan con { y acaban en }, por lo que la variable dejar de existir cuando se
cierre el corchete que est justo antes que ella en el cdigo.
En Java no se permite la definicin de una variable con el mismo nombre de otra variable de
mbito superior (como s se permite en C):
{
int x = 12;
{
int x = 96; /* ilegal en Java, no en C++ */
}
}

Operadores
Los operadores bsicos de Java son + , - , * , / para suma, resta, producto y divisin. El
operador / representa la divisin de enteros si ambos operandos son enteros. Su mdulo
puede obtenerse mediante el operador %.
Adems existen los operadores decremento e incremento: -- y ++ respectivamente. La
operacin que realizan son incrementar y decrementar en una unidad a la variable a la que se
aplican. Su accin es distinta segn se apliquen antes (++a) o despus (a++) de la variable.
Adems de los operadores aritmticos, tenemos los operadores lgicos:
!
==
!=
<
>
<=
>=
&&
&
||
|

Not lgico
Test de igualdad
Test de desigualdad
Menor que
Mayor que
Menor o igual que
Mayor o igual que
And lgico
And lgico (evala todos los trminos siempre)
Or lgico
Or lgico (evala todos los trminos siempre)

Respecto de la asignacin, Java dispone, adems de =, de otros operadores. Se trata de


versiones abreviadas del operador (=) que realizan operaciones acumulativas sobre una
variable. La tabla muestra estos operadores y su equivalencia con el uso del operador igual
(=).

Pgina 6 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Operador
+=
-=
*=
/=
%=

Utilizacin
op1 += op2
op1 -= op2
op1 *= op2
op1 /= op2
op1 %= op2

Expresin equivalente
op1 = op1 + op2
op1 = op1 - op2
op1 = op1 * op2
op1 = op1 / op2
op1 = op1 % op2

Operador instanceof
El operador instanceof permite saber si un objeto pertenece o no a una determinada clase. Es
un operador binario cuya forma general es,
objectName instanceof ClassName
Y que devuelve true o false segn el objeto pertenezca o no a la clase. O sea que, por
polimorfismo, tambin devuelve true cuando el objeto es de una clase hija de ClassName, o
bien cuando ClassName es una interfaz y el objeto la implementa.
Operador condicional (?)
Este operador, tomado de C/C++, permite realizar bifurcaciones condicionales sencillas. Su
forma general es la siguiente:
booleanExpression ? res1 : res2
Donde se evala booleanExpression y se devuelve res1 si el resultado es true, y res2 si el
resultado es false. Es el nico operador ternario (tres argumentos) de Java. Como todo
operador que devuelve un valor puede ser utilizado en una expresin.

Estructuras de decisin
Las estructuras de decisin permiten ejecutar una de entre varias acciones, en funcin del
valor de una expresin lgica o relacional. Se tratan de estructuras muy importantes, ya que
son las encargadas de controlar el flujo de ejecucin de un programa.
Existen dos bifurcaciones diferentes: if y switch.
If
Existen tres formas de implementar esta estructura, y son: if, if else e if else if. A
continuacin se explicara cada una de estas implementaciones:
if: esta estructura permite ejecutar un conjunto de sentencias en funcin del valor que
tenga la expresin de comparacin (se ejecuta si la expresin de comparacin tiene valor
true). Tiene la forma siguiente:
if (expresion) {
sentencias;
}

Pgina 7 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Las llaves {} sirven para agrupar en un bloque las sentencias que se han de ejecutar, y no son
necesarias si slo hay una sentencia dentro del if.
if else: anloga a la anterior, de la cual es una ampliacin. Las sentencias incluidas en el
else se ejecutan en el caso de no cumplirse la expresin de comparacin (false):
if (expresion) {
sentencias1;
} else {
sentencias2;
}
if else if: Permite introducir ms de una expresin de comparacin. Si la primera
condicin no se cumple, se compara la segunda y as sucesivamente. En el caso de que no se
cumpla ninguna de las comparaciones se ejecutan las sentencias correspondientes al else.
if (expresion1) {
sentencias1;
} else if (expresion2) {
sentencias2;
} else if (expresion3) {
sentencias3;
} else {
sentencias4;
}
Switch
Se trata de una alternativa a la bifurcacin if else if cuando se compara la misma
expresin con distintos valores. Su forma general es la siguiente:
switch (expresion) {
case valor1:
sentencias1;
break;
case valor2:
sentencias2;
break;
case valor3:
sentencias3;
break;
case valor4:
sentencias4;
break;
case valor5:
sentencias5;
break;
case valor6:
sentencias6;
break;
[default:
sentencias7;]

Pgina 8 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
}
Las caractersticas ms relevantes de switch son las siguientes:
1. Cada sentencia case se corresponde con un nico valor de expresin. No se pueden
establecer rangos o condiciones sino que se debe comparar con valores concretos de tipo
entero (byte, short, int) o con constantes de enumeracin.
2. Los valores no comprendidos en ninguna sentencia case se pueden gestionar en default,
que es opcional.
3. En ausencia de break, cuando se ejecuta una sentencia case se ejecutan tambin todas las
case que van a continuacin, hasta que se llega a un break o hasta que se termina el switch.

Estructuras repetitivas
Se utilizan para realizar un proceso repetidas veces. Se denomina tambin bucle, lazo o loop.
El cdigo incluido entre las llaves {} (opcionales si el proceso repetitivo consta de una sola
lnea), se ejecutar mientras se cumpla unas determinadas condiciones. Hay que prestar
especial atencin a los bucles infinitos, hecho que ocurre cuando la condicin de finalizar el
bucle (expresion) no se llega a cumplir nunca. Se trata de un fallo muy tpico.
Bucle while
Las sentencias se ejecutan mientras expresin sea true.
while (expresion) {
sentencias;
}
Bucle for
La forma general del bucle for es la siguiente:
for (inicializacion; expresion; avance) {
sentencias;
}
Que es equivalente a utilizar while en la siguiente forma:
inicializacion;
while (expresion) {
sentencias;
avance;
}
La sentencia o sentencias de inicializacin se ejecutan al comienzo del for, y la o las
sentencias de avance se ejecutan despus de cada ciclo. La expresin se evala al comienzo
de cada iteracin. El bucle termina cuando la expresin de comparacin (condicin de corte)
toma el valor false. Cualquiera de las tres partes puede estar vaca. La inicializacin y el
incremento pueden tener varias expresiones separadas por comas.
Bucle do while

Pgina 9 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Es similar al bucle while pero con la particularidad de que el control est al final del bucle (lo
que hace que el bucle se ejecute al menos una vez). Una vez ejecutados las sentencias, se
evala la condicin: si resulta true se vuelven a ejecutar las sentencias incluidas en el bucle,
mientras que si la condicin se evala a false finaliza el bucle.
do {
statements
} while (booleanExpression);

Sentencias break y continue


La sentencia break es vlida tanto para en los bucles como en el switch. Hace que se salga
inmediatamente del bucle o bloque que se est ejecutando, sin realizar la ejecucin del resto
de las sentencias.
La sentencia continue se utiliza en los bucles (no en bifurcaciones). Finaliza la iteracin i
que en ese momento se est ejecutando (no ejecuta el resto de sentencias que hubiera hasta
el final del bucle), vuelve al comienzo del bucle y comienza la siguiente iteracin (i+1).

Sentencia return
Otra forma de salir de un bucle (y de un mtodo) es utilizar la sentencia return. A diferencia
de continue o break, la sentencia return sale tambin del mtodo o funcin. En el caso de
que la funcin devuelva alguna variable, este valor se deber poner a continuacin del return
(return value;).

Arrays
En Java los arrays son un objeto. Como tales se crean mediante el comando new. La sintaxis
en la definicin de un array es la siguiente:
Tipo_datos[] nombre_array = new Tipo_datos[tamano_array];
Tipo_datos es el tipo de los datos que se almacenarn en el array (int, char, String... o
cualquier objeto). Tamano_array es tamao que le queremos dar a este array. Veamos un
ejemplo:
int[] edades = new int[10];
En este ejemplo hemos definido un array llamado edades, en el que podremos almacenar 10
datos tipo entero. El primer elemento de un array se sita en la posicin 0, exactamente igual
que en C. Si quisisemos realizar un bucle que recorriese los elementos de este array
escribiramos un cdigo del tipo:
for(int i= 0; i< 10; i++){
System.out.println(Elemento + i + edades[i]);
}

Pgina 10 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Veremos ms sobre arreglos ms adelante en este manual (ver Conjuntos de datos).

Programacin orientada a objetos


En los aos 60 la programacin se realizaba de un modo clsico (no orientado a objetos). Un
programa era un cdigo que se ejecutaba, los trozos de cdigo que se podan emplear en
varias ocasiones a lo largo del programa (reusar) se escriban en forma de procedimientos que
se invocaban desde el programa, y esta era la nica capacidad de reuso de cdigo posible.
Segn los cdigos se fueron haciendo ms grandes y complejos este estilo de programacin se
haca ms inviable: es difcil programar algo de grandes dimensiones con este estilo de
programacin. La nica posibilidad de repartir trozos de cdigo relativamente independientes
entre programadores son los procedimientos, y al final hay que juntar todos estos con el
programa central que los llama, siendo frecuente encontrar problemas al unir estos trozos de
cdigo.
En los aos 70 se empez a imponer con fuerza otro estilo de programacin: POO,
programacin orientada o objetos (en la literatura suele aparecer como OOP, Object Oriented
Programing). Aqu un programa no es un cdigo que llama a procedimientos, aqu un
programa es un montn de objetos, independientes entre si, que dialogan entre ellos
pasndose mensajes para llegar a resolver el problema en cuestin.
A un objeto no le importa en absoluto como est implementado otro objeto, que cdigo tiene
o deja de tener, que variables usa.... slo le importa a qu mensajes es capaz de responder.
Un mensaje es la invocacin de un mtodo de otro objeto. Un mtodo es muy semejante a un
procedimiento de la programacin clsica: a un mtodo se le pasan uno, varios o ningn dato
y nos devuelve un dato a cambio o no devuelve nada.
Si hay que repartir un programa de grandes dimensiones entre varios programadores a cada
uno se le asignan unos cuantos objetos, y en lo nico que tendrn que ponerse de acuerdo
entre ellos es en los mensajes que se van a pasar; la forma en que un programador
implemente sus objetos no influye en absoluto en lo que los dems programadores hagan.
Esto es as gracias a que los objetos son independientes unos de otros (cuanta mayor sea la
independencia entre ellos de mayor calidad sern).
Si analizamos lo que hemos dicho hasta aqu de los objetos veremos que estos parecen tener
dos partes bastante diferenciadas: la parte que gestiona los mensajes, que ha de ser conocida
por los dems, y que no podremos cambiar en el futuro sin modificar los dems objetos (s es
posible aadir nuevos mtodos para dar nuevas funciones al objetos sin modificar los mtodos
ya existentes). La otra parte es el mecanismo por el cual se generan las acciones requeridas
por los mensajes el conjunto de variables que se emplean para lograr estas acciones. Esta
segunda parte es, en principio, totalmente desconocida para los dems objetos (a veces no es
as, pero es lo ideal en un buena OOP). Por ser desconocida para los dems objetos podemos
en cualquier momento modificarla sin que a los dems les importe, y adems cada
programador tendr total libertad para llevarla a cabo como l considere oportuno.
La OOP permite abordar con ms posibilidades de xito y con un menor coste temporal
grandes proyectos de software, simplificndole adems la tarea al programador.

Clases y herencia
Una clase es la plantilla que usamos para crear los objetos. Todos los objetos pertenecen a
una determinada clase. Un objeto que se crea a partir de una clase se dice que es una
instancia de esa clase. Las distintas clases tienen distintas relaciones de herencia entre si: una
clase puede derivarse de otra, en ese caso la clase derivada o clase hija hereda los mtodos y

Pgina 11 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
variables de la clase de la que se deriva o clase padre. En Java todas las clases tienen como
primer padre una misma clase: la clase Object.
Definicin de una clase
La forma ms general de definicin de una clase en Java es:
[modificador [,modificador*]] class NombreClase [extends
nombreClasePadre] [implements nombreInterface [,nombreInterface*]] {
DeclaracinDeVariables;
DeclaracinDeMtodos;
}
Los campos que van entre corchetes son optativos. NombreClase es el nombre que le
queramos dar a nuestra clase, nombreClasePadre es el nombre de la clase padre, de la cual
hereda los mtodos y variables. Finalmente, tras la palabra implements se ponen todas las
interfaces (separadas por coma) que implementa la clase.
Slo podemos tener una clase public por unidad de compilacin, aunque es posible no tener
ninguna.

Creacin y referencia a objetos


Un objeto en el ordenador es esencialmente un bloque de memoria con espacio para guardar
las variables de dicho objeto. Crear el objeto es sinnimo de reservar espacio para sus
variables, inicializarlo es darle un valor a estas variables. Para crear un objeto se utiliza el
comando new. Vemoslo sobre un ejemplo:
class Fecha{
int dia,mes,ano;
Fecha(){
dia=1;
mes = 1;
ano = 1900;
}
Fecha (int _dia, int _mes, int _ano){
dia= _dia;
mes = _mes;
ano = _ano;
}
}
Fecha hoy;
hoy = new Fecha();
Con el primer comando hemos creado un puntero que apunta a una variable tipo fecha, como
est sin inicializar apuntara a null. Con el segundo inicializamos el objeto al que apunta hoy,
reservando espacio para sus variables. El constructor las inicializar, tomando el objeto hoy el
valor 1-1-1900.

Pgina 12 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Fecha unDia = new Fecha(8,12,1999);
Con esta sentencia creamos una variable que se llama unDia con valor 8-12-1999.
Una vez creado un objeto ser posible acceder a todas sus variables y mtodos pblicos, as
por ejemplo en el ejemplo anterior unDia.dia = 8. Si la variable fuese privada (como en el
ejemplo) solo podra acceder a ella el objeto particular al que pertenece esa variable. El nico
capaz de acceder a los atributos privados del objeto es el objeto mismo:
class Fecha{
private int dia;
private int mes
private int ano;
Fecha() {
dia=1;
mes = 1;
ano = 1900;
}
Fecha (int ndia, nmes, nano) {
dia= ndia;
mes = nmes;
ano = nano;
}
}
De este modo no podramos acceder a las variables de la clase fecha, para acceder a ella
tendramos que hacerlo mediante mtodos que nos devolviesen su valor. A esto se le
denomina encapsulamiento. Esta es la forma correcta de programar OOP: no debemos dejar
acceder a las variables de los objetos por otro procedimiento que no sea paso de mensajes
entre mtodos.
A su vez, cuando creamos un objeto de una clase padre, luego podemos apuntar con ese
objeto a un objeto de una clase hija. Por ejemplo:
class Persona {
protected int dni;
}
class Cliente extends Persona {
protected int nroCliente;
}
public class Test {
public static void main (String args []) {
Persona javi;
Cliente hectorCampora;
javi = new Persona();
hectorCampora = new Cliente();
javi = hectorCampora;
}
}

Constructores

Pgina 13 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

El constructor es un mtodo cuyo nombre coincide con el nombre de la clase y que nunca
devuelve ningn tipo de dato, no siendo necesario indicar que el tipo de dato devuelto es void.
Pueden tener distintos accesos (public, protected, private). Este mtodo es llamado
cuando se construye un objeto, es el mtodo responsable de la inicializacin del objeto.
Los constructores se emplean para inicializar los valores de los objetos y realizar las
operaciones que sean necesarias para la generacin de este objeto (crear otros objetos que
puedan estar contenidos dentro de este objeto, abrir un archivo o una conexin de
internet.....).
Como cualquier mtodo, un constructor admite sobrecarga. Cuando creamos un objeto (ya se
ver ms adelante como se hace) podemos invocar al constructor que ms nos convenga.
class animal{
int edad;
String nombre;
public animal(){
}
public animal(int _edad, String _nombre){
edad = _edad;
nombre = _nombre;
}
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}

Mtodo finalize
En Java no existen los destructores. Para suplir esta ausencia existe un mtodo en la clase
Object que es llamado cuando el recolector de basura ha determinado la inalcanzabilidad de
un objeto y se dispone a "limpiarlo" de la pila. Se trata del mtodo
protected void finalize() throws Throwable;
Si nuestra clase redefine este mtodo, cumplimos con el mismo objetivo que si tuvisemos un
destructor.

Pgina 14 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

this
Es una variable especial de slo lectura que proporciona Java. Contiene una referencia al
objeto en el que se usa dicha variable. A veces es til que un objeto pueda referenciarse a si
mismo:
class Cliente{
public Cliente(String n){
//Llamamos al otro constructor. El empleo de this ha de ser
//siempre en la primera lnea dentro del constructor.
this(n, Cuenta.nuevo_numero());
.....
}
public Cliente (String n, int a){
nombre = n;
numero_cuenta = a;
}
.....
}
Otro posible uso de this, que ya se ha visto en ejemplos anteriores es diferenciar entre
variables locales de un mtodo o constructor y variables del objeto.
public animal(int edad, String nombre){
//this.edad = variable del objeto perro
//edad = variable definida slo dentro del constructor
this.edad =edad;
this.nombre=nombre;
}

super
Del mismo modo que this apunta al objeto actual, tenemos otra variable, super, que apunta
a la clase de la cual se deriva nuestra clase
class Gato {
void hablar(){
System.out.println("Miau");
}
}
class GatoMagico extends Gato {
boolean gente_presente;
void hablar(){
if(gente_presente)
//Invoca al mtodo sobreescrito de la clase padre
super.hablar();
else
System.out.println("Hola");
}

Pgina 15 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
}
Uno de los principales usos de super es, como ya se emple en un ejemplo, llamar al
constructor de la clase padre. En este caso, la llamada a super debe encontrarse en la primer
lnea del constructor.

Atributos y mtodos estticos


A veces, los atributos no se refieren a un objeto puntual, sino ms bien a la clase que engloba
los objetos. Esto mismo puede ocurrir con los mtodos. Estos atributos y mtodos referidos a
la clase se llaman estticos, y se definen anteponiendo el modificador static.
Desde el contexto de un mtodo estatico, no puede hacerse referencia a this (pues se trata
de una referencia al objeto actual, y en este contexto no hay un objeto actual) ni a ningn
mtodo o atributo de instancia (sin explicitar el objeto propietario de ese atributo o mtodo).
Para inicializar estos atributos que pueden ser llamados antes de que se cree ningn objeto (o
sea que no podemos contar con el constructor para inicializarlos) existe el inicializador
esttico. Se trata de un mtodo que no devuelve nada, sin modificador de acceso, y sin
parmetros.
static {
cntAlumnos = 25;
}
}

Modificadores de acceso
Los modificadores son palabras reservadas que asignan, algunos, cierta caracterstica o
particularidad a una clase, a una interfaz, a un atributo o bien a un mtodo. Mientras que
otros, a veces llamados los de visibilidad o de accesibilidad, determinan el mbito del
elemento, desde dnde se va a poder acceder a l, o sea, qu clases pueden utilizarlo.
Los modificadores de accesibilidad son public, protected y private. Si no se utiliza ninguno
de ellos, se asume una visbilidad por defecto segn el caso. Este comportamiento se muestra
en la tabla siguiente en la columna "default" (algunos llaman "package" a este
comportamiento por defecto, dado que la idea siempre es que el elemento sea accesible slo
desde el paquete donde se encuentra).
Los modificadores de caractersticas son static, final, abstract, transient, volatile,
synchronized, native y strictfp.
A continuacin hay una tabla sobre los modificadores ms usados.

Pgina 16 de 62

public

class

visible desde otros paquetes

protected

N/A

private

N/A

mtodo

visible desde otros paquetes - visible solo dentro del paquete - visible slo dentro de la clase hereda
hereda
no hereda

atributo

visible desde otros paquetes - visible solo dentro del paquete - visible slo dentro de la clase hereda
hereda
no hereda

interface

visible desde otros paquetes

N/A

N/A

inner class

visible desde otros paquetes - visible solo dentro del paquete - visible slo dentro de la clase hereda
hereda
no hereda

mtodos de
interfaces

visible desde otros paquetes hereda

atributos de
interfaces

visible desde otros paquetes hereda

N/A

N/A

N/A

N/A

default

static

final

abstract

N/A

No puede
No puede
tener clases tener clases
hijas - Si es hijas - Si es
final, no
abstract, no
puede ser
puede ser
abstract
final

protected

Mtodo
esttico

Debe estar
en una clase
abstracta, y
No puede ser slo puede
redefinido usar public o
protected. El
mtodo no
tiene cdigo.

protected

Atributo
esttico

visible slo dentro del paquete

Una vez
seteado el
valor, no
puede
modificarse

N/A

No puede
tener
N/A
interfaces
hijas
No puede
No puede
tener clases tener clases
hijas - Si es hijas - Si es
final, no
abstract, no
puede ser
puede ser
abstract
final

visible slo dentro del paquete

N/A

protected

Clase
esttica

public

N/A

N/A

El mtodo no
tiene cdigo

atributo de
clase

Una vez
seteado el
valor, no
puede
modificarse

N/A

public static final

Los menos usados son:


transient: Se aplica a atributos. Indica que el mismo no debe ser tenido en cuenta en la
serializacin.
synchronized: Se aplica a mtodos. Indica que debe establecerse un bloqueo sobre la clase (si el
mtodo es esttico) o sobre el objeto (si es de instancia) durante la ejecucin del mtodo.
volatile: Se aplica a atributos estticos. Indica que el atributo se bloquee con cada acceso para
asegurar sincronismo cuando el atributo ser accedido desde cdigo "no-synchronized".
native: Se aplica a mtodos, y especifica que el cuerpo del mtodo se encuentra en otro archivo,
escrito en otro lenguaje dependiente de la plataforma.Dependiente de
strictfp: Se aplica a mtodos y clases. Aplicado a un mtodo, todos los clculos de punto flotante se
realizan estrictamente de acuerdo al estndar IEEE 754. Todos los valores -incluyendo los
intermedios- deben ser expresados como flotantes o doubles IEEE. Si el modificador se aplica a una
clase, todos los mtodos de la clase son, implcitamente, strictfp.
Un listado de todas las combinaciones posibles:
Modificador

Clase

Atributo

Mtodo

Constructor

Bloque de cdigo

public
protected
default
private
final
abstract
static
native
transient
volatile
synchronized

s
no
s
no
s
s
no
no
no
no
no

s
s
s
s
s
no
s
no
s
s
no

s
s
s
s
s
s
s
s
no
no
s

s
s
s
s
no
no
no
no
no
no
no

no
no
s
no
no
no
s
no
no
no
s

Herencia
Cuando en Java indicamos que una clase extends (extiende) otra clase estamos indicando que es
una clase hija de esta y que, por lo tanto, hereda todos sus mtodos y variables. Este es un poderoso
mecanismo para la reusabilidad del cdigo. Al heredar de una clase partimos de su estructura de
variables y mtodos, y luego slo aadimos lo que necesitemos o modificamos lo que no se adapta a
nuestros requerimientos. Veamos un ejemplo:
class animal{
protected int edad;
String nombre;
public animal(){
}
public animal(int _edad, String _nombre){
edad = _edad;
nombre = _nombre;
}
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);

Pgina 18 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}
//La clase perro extiende a animal, heredando sus mtodos y
//variables
public class perro extends animal{
perro(){
edad = 0;
nombre ="Tobi";
}
perro(int edad, String nombre){
//Esta sentencia invoca a un constructor de la clase padre.
super(edad,nombre);
}
//Mtodo esttico que recibe un objeto de tipo perro e
//invoca a su mtodo get_edad()
static void get1(perro dog){
//El mtod get_edad() no est definido en perro, lo ha
//heredado de animal.
dog.get_edad();
}
public static void main (String[] args){
//Creamos un objeto de tipo perro
perro dog = new perro(8,"Bambi");
//Invocamos al mtodo esttico get1 pasndole el objeto
//de tipo perro creado.
perro.get1(dog);
}
}
Cuando se define un mtodo de clase, no podrn existir mtodos de instancia con el mismo nombre
(an cuando devuelvan tipos distintos), ni en la clase que lo defini, ni en las clases que heredan de
ella.
Existen clases que es deseable que existan slo para agrupar un comportamiento comn entre otras
clases; pero esta clase padre no interviene directamente en el negocio, sino a travs de sus clases
hijas. En estos casos, la clase debe declararse abstract, y no podr ser instanciada.

Polimorfismo: Sobrecarga y Redefinicin de mtodos


El polimorfismo es la caracterstica de la POO por la cual un objeto puede comportarse de distintas
manderas segn el entorno; puntualmente, puede comprtarse como un objeto de una clase ancestra o
como un objeto que implementa cierta interfaz.

Pgina 19 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Para cumplimentar esto, el compilador se ha diseado utilizando late binding, esto es, la llamada al
mtodo es enlazada con el mtodo puntual en tiempo de ejecucin, en vez de enlazarse en tiempo de
compilacin.
Un aspecto del polimorfismo es lograr que clases hijas modifiquen el comportamiento provisto por el
padre para adaptarlo a sus requerimientos. Este es el concepto de redefinicin (override), escribir un
mtodo en una clase hija con -casi- la misma cabecera que la del mtodo homnimo en la clase
padre. Las nicas diferencias pueden ser:

ampliar la visibilidad

reducir la lista de excepciones lanzadas


Por ejemplo:
class animal{
protected int edad;
String nombre;
public animal(){
}
public animal(int _edad, String _nombre){
edad = _edad;
nombre = _nombre;
}
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}
public class perro2 extends animal{
perro2(){
edad = 0;
nombre ="Tobi";
}
perro2(int edad, String nombre){
super(edad,nombre);
}
static void get1(perro2 dog){
dog.get_edad();

Pgina 20 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
//Cuando ejecutemos este mtodo en vez de ejecutarse
// el cdigo de la clase padre se ejecutar el cdigo de la
// clase hija, ya que sta ha sobreescrito este mtodo.
dog.get_nombre(11);
}
//Sobreescribe al mtodo de la clase padre.
public void get_nombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
perro2 dog = new perro2(8,"hola");
perro2.get1(dog);
}
}
Otro aspecto del polimorfismo sera pretender que el comportamiento de una clase (sus mtodos) se
adapten a distintas peticiones del mismo tipo, o dicho de otra manera, el mismo nombre de mtodo
(peticin) con distina informacin (parmetros).
Java admite lo que se llama sobrecarga (overload) de mtodos: puede haber varios mtodos con el
mismo nombre pero a los cuales se les pasan distintos parmetros. El tipo devuelto no influye: no
puede haber dos mtodos que reciban los mismos parmetros y que devuelvan tipos distintos. Segn
los parmetros que se le pasen se invocar a uno u otro mtodo:
class animal{
int edad;
String nombre;
public void nace(){
System.out.println("Hola mundo");
}
public void get_nombre(){
System.out.println(nombre);
}
public void get_nombre(int i){
System.out.println(nombre +" " +edad);
}
public void get_edad(){
System.out.println(edad);
}
}

Interfaces
En Java no est soportada la herencia mltiple, esto es, no est permitido que una misma clase pueda
heredar las propiedades de varias clases padres. En principio esto pudiera parecer una propiedad
interesante que le dara una mayor potencia al lenguaje de programacin, sin embargo los creadores
de Java decidieron no implementar la herencia mltiple por considerar que esta aade al cdigo una

Pgina 21 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
gran complejidad (lo que hace que muchas veces los programadores que emplean programas que s la
soportan no lleguen a usarla).
Sin embargo para no privar a Java de la potencia de la herencia mltiple sus creadores introdujeron
un nuevo concepto: el de interface. Una interface (o interfaz) es formalmente como una clase, con
tres diferencias: primero, sus mtodos no tienen cuerpo, slo sabecera; segundo, a la hora de
definirla, en vez de emplear la palabra clave class se emplea inteface; y tercero, todos los atributos
sern implcitamente public static final. Vemoslo con un ejemplo:
interface animal{
public int edad = 10; /* es un atributo esttico, an cuando no se
explicite*/
public String nombre = "Bob";
public void nace();
public void get_nombre();
void get_nombre(int i);
}
Cabe preguntarnos cul es el uso de una interface si sus mtodos estn vacos. Bien, cuando una
clase implementa una interface lo que estamos haciendo es una promesa de que esa clase va a
implementar todos los mtodos de la interface en cuestin; de hecho, hasta que no los implemente no
podr ser compilada. De esta forma puede abstraerse un comprtamiento dejando que distintas clases
lo implementen a su manera. Con esto no ahorramos cdigo. Lo que se busca aqu es independencia
de implementacin, algo muy distinto de la reutilizacin de cdigo que se busca con la herencia.
Vemoslo con un ejemplo de una clase que implementa la anterior interface:
interface animal{
public int edad = 10;
public String nombre = "Bob";
public void nace();
public void get_nombre();
void get_nombre(int i);
}
public class perro3 implements animal{
perro3(){
get_nombre();
get_nombre(8);
}
//Comprubese como si cambiamos el nombre del mtodo a nac()
//no compila ya que no henos sobreescrito todos los mtodos
//de la interfaz.
public void nace(){
System.out.println("hola mundo");
}

Pgina 22 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
public void get_nombre(){
System.out.println(nombre );
}
public void get_nombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
perro3 dog = new perro3();
// Compruebese como esta lnea da un error al compilar
// debido a intentar asignar un valor
// a una variable final
// dog.edad = 8;
}
}
Las variables que se definen en una interface llevan todas ellas los modificadores static final, an
cuando no est escrito, y es obligatorio darles un valor dentro del cuerpo de la interface. Adems no
pueden llevar modificadores private ni protected, slo public. Su funcin es la de ser una especie
de constantes para todos los objetos que implementen dicha interface.
Por ltimo decir que aunque una clase slo puede heredar propiedades de otra clase puede
implementar cuantas interfaces se desee, recuperndose as en buena parte la potencia de la herencia
mltiple, como un beneficio extra de las interfaces.
interface animal1{
public int edad = 10;
public String nombre = "Bob";
public void nace();
}
interface animal2{
public void get_nombre();
}
interface animal3{
void get_nombre(int i);
}
public class perro4 implements animal1,animal2,animal3{
perro4(){
get_nombre();
get_nombre(8);
//edad = 10; no podemos cambiar este valor
}
public void nace(){
System.out.println("hola mundo");
}
public void get_nombre(){
System.out.println(nombre );
}

Pgina 23 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
public void get_nombre(int i){
System.out.println(nombre +" " +i);
}
public static void main (String[] args){
perro4 dog = new perro4();
}
}

Clases Internas
Las clases internas (o "embebidas", o "inner") son clases que se encuentran dentro de la definicin de
otra clase. Esto hace suponer que el uso de stas es representar esos casos de inclusin donde la
clase includa tiene cierta complejidad, y tiene un vnculo tan fuerte con la clase envolvente que no es
utilizada nunca por separado, sino siempre como parte de la clase envolvente.
Las posibilidades son:

Tener una clase como un atributo esttico de otra clase. En este caso la clase interna puede
acceder al entorno esttico de la clase (atributos y mtodos estticos).

Tener la clase interna como un atributo. Entonces la clase interna puede acceder a todos los
atributos y mtodos de la clase externa. Para referirse al objeto envolvente actual, puede
utilizarse MiClaseExterna.this.

Encontrar la clase interna definida dentro del cuerpo de un mtodo. La clase interna puede
entonces acceder a toda la informacin del objeto externo, ms una instantnea de los valores
de las variables locales del mtodo.

Tener una clase annima. Estas clases se definen en la llamada a un mtodo (entre los
parmetros).
Las sintaxis para la definicin de una clase annima es la siguiente, dependiendo de si hereda de una
clase o si implementa una interfaz:
new nombreClasePadre ([argumentosDelConstructor]) { cuerpoDeLaClase }
o:
new nomreDeLaInterfaz () { cuerpoDeLaClase }

Clases de utilidad y uso comn


Clase String
Como vimos anteriormente, un objeto que pertenezca a esta clase almacenar cadenas de caracteres.
Una particularidad de esta clase es que los objetos String son constantes; sus valores no pueden
modificarse una vez que se crearon. La clase StringBuffer soporta cadenas modificables. Esto no
significa que el siguiente cdigo lanze un error
String aux = "txt";
aux = "txt nuevo";

Pgina 24 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
sino que en la segunda lnea, la variable aux pasa a apuntar a otro objeto, a otra direccin de
memoria, en vez de modificarse la informacin guardada en la primera direccin.
Linea 1:

aux

txt

Linea 2:
aux

txt

txt nuevo

Otra peculiaridad de esta clase es que la instanciacin de nuevos objetos no requiere una llamada
explcita al constructor. En vez de esto:
String aux = new String("algo");
se utiliza esto (por facilidad; lo anterior no producira error alguno):
String aux = "algo";
No es necesario crear una variable para acceder a los mtodos de la clase; los mismos pueden
accederse desde cualquier constante de cadena. El siguiente cdigo es enteramente vlido:
if ("ratoncito".length() > 5) {
Java provee un soporte especial para el operador de concatenacin (+) de cadenas, y para la
conversin de otros objetos a String. La concatenacin se implementa a travs de la clase
StringBuilder o bien de la clase StringBuffer, con el mtodo append. Las conversiones estn
implementadas a travs del mtodo toString de la clase Object.
Los mtodos ms usados son:
char charAt(int index): el mtodo devuelve el caracter que se enuentra en la posicin
"index" (la primera posicin es cero).
"ratoncito".charAt(4) devuelve 'n'

int compareTo(String anotherString): Compara la cadena con "anotherString" y


devuelve:
0 si ambas cadenas son iguales
<0 si la cadena se encuentra antes que la cadena argumento
>0 si la cadena se encuentra despus de la cadena argumento
El encontrarse antes y despus depende del largo de las cadenas, y del orden de los
caracateres que forman las cadenas en el conjunto Unicode utilizado.
"ratoncito".compareTo("ratonillo") devuelve un valor menor que cero porque en la

Pgina 25 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

posicin cinco (comenzando desde cero) el caracter 'i' es posterior al caracter 'c'. Tambin
existe el mtodo compareToIgnoreCase que no toma en cuenta diferencias entre maysculas y
minsculas.
boolean equals(Object a): Compara la cadena con un objeto, y devuelve true si el objeto a
no es nulo, y si a representa la misma secuencia de caracteres que la cadena. Tambin existe
el mtodo equalsIgnoreCase que no toma en cuenta las diferencias entre maysculas y
minsculas.
"ratoncito".equals("Ratoncito") devuelve false
int indexOf(char c): Devuelve la posicin donde primero se encontr el caracter 'c' en la
cadena. Si el caracter no se encontr devuelve -1. Adems, se puede especificar desde qu
posicin empezar la bsqueda con el mtodo int indexOf(char c, int startFrom), y se puede
buscar una cadena en vez de un caracter. Tambin existen los mtodos lastIndexOf con las
mismas consideraciones, pero buscando desde atrs hacia adelante en la cadena.
int length(): devuelve el largo de la cadena
"ratoncito".length() devuelve 9
String substring(int beginIdex, int endIndex): devuelve la subcadena que se
encuentra entre la posicin beginIndex y la posicin endIndex-1. El segundo argumento puede
no existir; en ese caso, la subcadena va hasta el final de la cadena original.
"ratoncito".substring(4,6) devuelve "n"
String trim(): devuelve una copia de la cadena, sin los espacios al comienzo y al final de la
misma.
" ratoncito ".trim() devuelve "ratoncito"

String toUpperCase(): convierte todos los caracteres de la cadena a maysculas.


"R53tulP".toUpperCase() devuelve "R53TULP"

String toLowerCase(): convierte todos los caracteres de la cadena a minsculas.


"R53tulP".toLowerCase() devuelve "r53tulp"
valueOf: es un mtodo esttico que puede recibir un boolean, un char, un int, un long, un
float, un double o incluso un objeto; en cualquier caso, devolver una representacin en
String del argumento pasado.
String.valueOf(67.9) devuelve "67.9"

Ms informacin en http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html

Clase Math
La clase java.lang.Math contiene mtodos para realizar las operaciones numricas bsicas, tales
como la exponenciacin, la logaritmacin, la raz cuadrada, las funciones trigonomtricas, etctera.
Todas las propiedades y los mtodos de la clase son estticos, por lo que para acceder a ellos no es
necesario instanciar la clase en ningn objeto en particular.
Adems de mtodos, la clase provee las constantes Math.E (base de los logaritmos neperianos),
Math.PI (constante Pi, ambos son double).
Por ejemplo, con Math.pow(double a, double b) obtenemos el resultado de elevar el nmero a a
la potencia b.
Otra funcin importantsima es el mtodo random() para generar nmeros aleatorios. A decir verdad,
para la generacin de nmeros aleatorios la clase Math recurre a otra clase, puntualmente
java.util.Random.
Adems de esta clase (java.lang.Math), se cuenta con un paquete (java.Math) donde se encuentran
definidas unas clases de tipos de datos muy usuales: BigInteger (para modelar un entero grande) y

Pgina 26 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
BigDecimal (para modelar un nmero real exacto -hasta cierta precisin- y no por aproximacin como
float y double). stas suelen ser necesarias para comnicarse con la base de datos.
// Entero aleatorio entre 5 y 27, ambos inclusive
// (la distancia del intervalo es 22)
alea = (int) ((Math.round(Math.random() * 22) + 5));
Ms informacin en http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html

Fechas
Para el manejo de fechas existen varias clases en Java. La principal de ellas es la clase
java.util.Date. Esta clase modela una fecha como la cantidad de milisegundos desde el primero de
Enero de 1970 a las 0:00:00 (a este momento se le denomina "poca"). Para obtener la fecha actual
basta con crear un objeto Date llamando al constructor por defecto.
Las clases java.sql.Date y java.sql.Timestamp fueron creadas para conectar a Java con las bases
de datos, proveyendo tipos de datos de fecha simple y de fecha ms hora respectivamente. Objetos
de estas clases son los que reciben los mtodos setDate y setTimestamp de la clase
PreparedStatement para asignar valores a los parmetros tipo DATE y DATETIME, siempre
respectivamente.
La clase abstracta Calendar apunta a un manejo mucho ms sofisticado de la fecha, con informacin
desde la era hasta el da de semana. La clase hija ms til para el mundo occidental es
GregorianCalendar.
Para el pasaje entre un objeto tipo Date y una cadena de texto se utiliza la clase SimpleDateFormat.
Al construir un objeto de esta clase se especifica un formato, que se utilizar para parsear la cadena
(String -> Date) y para formatear la fecha (Date -> String).
import
import
import
import

java.text.ParseException;
java.text.SimpleDateFormat;
java.util.Date;
java.util.GregorianCalendar;

public class DateTest {


public static void main(String[] args) {
Date dt = null;
SimpleDateFormat sdfEntrada = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat sdfSalida = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
GregorianCalendar cal = new GregorianCalendar();
// Parsear una cadena a un Date
// esto puede arrojar una excepcin ParseException
try{
dt = sdfEntrada.parse("18/8/1978");
}catch(ParseException pe){
System.out.println(pe.toString());
pe.printStackTrace();
}
// Formatear una fecha

Pgina 27 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
if (dt != null) System.out.println(sdfSalida.format(dt));
//Obtener informacin ms completa sobre la fecha
// Imprimir la zona horaria
System.out.println(cal.getTimeZone().getDisplayName());
// Imprimir el ao
System.out.println(cal.get(cal.YEAR));
// Imprimir booleano que indica si el ao es bisiesto o no
System.out.println(cal.isLeapYear(cal.get(cal.YEAR)));
// Imprimir las horas de diferencias respecto de Greenwich
System.out.println(cal.get(cal.ZONE_OFFSET)/(1000*60*60));
}
}
La salida por consola de la ejecucin de este programa es:
18/08/1978 00:00:00
Hora de Argentina
2006
false
-3

Conjuntos de Datos
Arreglos (arrays)
Un array es la forma ms bsica de agrupar datos. Todos los elementos del array deben ser del
mismo tipo. Los arreglos se crean con el operador new seguido del tipo y nmero de elementos. Una
vez creado el arreglo con un tamao determinado, ese tamao no puede ser modificado (los arreglos
son conjuntos de tamao fijo).
Se puede acceder al nmero de elementos de un arreglo con la variable miembro implcita length
(por ejemplo, arr.length). Se accede a los elementos de un arreglo con los corchetes [ ] y un ndice
que vara de 0 a length-1. Se pueden crear arreglos de objetos de cualquier tipo. Los elementos de un
arreglo se inicializan al valor por defecto del tipo correspondiente (cero para valores numricos, el
carcter nulo para char, false para boolean, null para referencias a objetos).
Como todos los objetos, los arreglos se pasan como argumentos a los mtodos por referencia. Se
pueden crear arreglos annimos (por ejemplo, crear un nuevo arreglo como argumento actual en la
llamada a un mtodo). La inicializacin de los arreglos se puede realizar de las siguientes maneras:
1. Con valores entre llaves {...} separados por comas.
2. Para arreglos de objetos, con varias llamadas a new dentro de las llaves {...}.
Si se igualan dos referencias a un arreglo no se copia el vector, sino que se tiene un arreglo con dos
nombres, apuntando al mismo y nico objeto. Para crear una referencia a un arreglo son posibles dos
formas:
double[] x; // preferible
double x[];
Luego se deber crear el arreglo en s con el operador new:
x = new double[100];

Pgina 28 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

La creacin de la referencia y la creacin del arreglo mismo se pueden unir en una sola lnea:
double[] x = new double[100];
String dias[] = {"lunes", "martes", "mircoles", "jueves", "viernes", "sbado",
"domingo"};
Un arreglo puede tener tambin dos dimensiones. En ese caso se les denomina matrices. Una matrz
se puede crear directamente en la forma:
int [][] mat = new int[3][4];
O bien se puede crear de modo dinmico dando los siguientes pasos:
1. Crear la referencia indicando con un doble corchete que es una referencia a matriz:
int[][] mat;
2. Crear el arreglo de referencias a las filas:
mat = new int[nfilas][];
3. Reservar memoria para los vectores correspondientes a las filas:
for (int i=0; i<nfilas; i++)
mat[i] = new int[ncols];
A continuacin se presentan algunos ejemplos de creacin de matrices
bidimensionales:
// crear una matriz 3x3
// se inicializan a cero
double mat[][] = new double[3][3];
int [][] b = {{1, 2, 3}, {4, 5, 6}};
int c = new[3][]; // se crea el arr. de referencias a matrices c
[0] = new int[5];
c[1] = new int[4];
c[2] = new int[8];
En el caso de una matriz b, b.length es el nmero de filas y b[0].length es el nmero de columnas
(de la fila 0). Por supuesto, las matrices bidimensionales pueden contener tipos primitivos de cualquier
tipo u objetos de cualquier clase.
Colecciones (Java Collections Framework)
Una coleccin es simplemente un objeto que agrupa mltiples elementos en una sola unidad. Las
colecciones se usan para almacenar, devolver, manipular y comunicar datos en conjunto. Tpicamente
representan datos de un conjunto natural de cosas. Y la Collections Framework es la arquitectura que
unifica la representacin y manipuacin de colecciones. Primeramente, este framework se compone de
una serie de interfaces que definen los tipos de conjuntos que pueden existir. Luego, existen
implementaciones genricas de estas interfaces.
Interfaces
A continuacin se muestran las interfaces que se encuentran en el ncleo de la JCF.

Pgina 29 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Un Set (o conjunto) es un tipo especial de coleccin, as como un SortedSet (o conjunto ordenado) es


un tipo especial de Set, y as sucesivamente. Ntese que en la jerarqua participan dos rboles
distintos: un Map (o mapa) no es una coleccin verdadera. La siguiente lista describe las interfaces del
ncleo:

Collection: es la raiz de la jerarqua de colecciones. Una Collection representa un grupo de


objetos conocidos como sus elementos. La interfaz Collection es el denominador comn que
todas las colecciones implementan, y se usa para pasar colecciones de un lugar a otro y para
manipularlas cuando se desea la mxima generalidad.
Set: es una coleccin que no puede contener elementos duplicados. Esta interfaz modela la
abstraccin matemtica del conjunto.
List: es una coleccin ordenada (se la suele llamar tambin secuencia). Las listas pueden
contener elementos duplicados. El usuario de una lista generalmente tiene control preciso
sobre dnde en la lista es insertado cada elemento y puede acceder a ellos mediante un ndice
entero (posicin).
Queue: es una coleccin tipo pila o cola, utilizada para contener varios elementos antes de su
procesamiento. Aparte de las operaciones bsicas de las colecciones, una cola provee
operaciones adicionales para la insercin, extraccin e inspeccin. Las colas tpicamente, pero
no necesariamente, ordenan los elementos en una forma FIFO (primero en entrar - primero en
salir). Cualquiera sea el orden utilizado, la cabeza de la cola es el elemento que extraer con
una llamada a remove o poll, y el final de la cola es donde se insertarn los elementos nuevos.
Ms informacin en http://java.sun.com/docs/books/tutorial/collections/interfaces/queue.html
Map: es un objeto que mapea claves a valores. Un mapa no puede contener claves duplicadas.
Cada clave se mapea a lo sumo a un valor.
SortedSet: es un conjunto que mantiene sus elementos en un orden ascendente.
SortedMap: es un mapa que mantiene sus mapeos en un orden ascendente de claves.

Clases Vector y ArrayList


La clase Vector implementa un arreglo de objetos que puede cambiar de tamao. Por debajo subyace
un arreglo de objetos (como atributo privado de la clase), y se muestran mtodos que se encargan de
hacer "crecer" -o mejor dicho, "crear un arreglo ms grande"- cuando se agotaron las posiciones del
arreglo subyacente. Estas propiedades tambin se aplican a la clase ArrayList, aunque las diferencia
es que la clase Vector tiene todos sus mtodos sincronizados (un aspecto que hace al paralelismo y
al bloqueo de objetos). Ambas clases son hijas de AbstractList (una implementacin de la interfaz
List
en
una
clase
abstracta)
y
permiten
elementos
null.
Ms
informacin
en
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html

Pgina 30 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Clases HashMap y Hashtable
Una tabla hash, o "vector asociativo", es una tabla que mapea "llaves" o "claves" a "valores".
Cualquier objeto no nulo puede ser usado como llave o como valor. La diferencia entre un objeto de la
clase Hashtable y un objeto de la clase HashMap es que el segundo permite valores nulos y la llave
nula. Adems, los mtodos provistos por HashMap son todos sincronizados. Estas clases no garantizan
el orden del mapa; en particular, no se garantiza que el orden permanecer constante en el tiempo.
Recorriendo colecciones
Existen dos formas de recorrer colecciones: con una construccin for-each, y usando Iterator
Construccin for-each
La construccin for-each, introducida en la versin 1.5 del JDK, permite recorrer una coleccin o un
arreglo usando un bucle for. El siguiente cdigo usa la construccin for-each para imprimir cada
elemento de una coleccin en una lnea distinta.
for (Object o : collection)
System.out.println(o);
Ms
informacin
sobre
esta
nueva
forma
de
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/for.html

uso

de

for

en

Clase Iterator
Un Iterator es un objeto que permite recorrer una coleccin y quitar elementos de ella
selectivamente. Se puede obtener un Iterator de una Collection llamando al mtodo iterator().
A continuacin se muestra la definicin de la interfaz Iterator.
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); //optional
}
El mtodo hasNext() devuelve true si la iteracin tiene ms elementos, y el mtodo next()
devuelve el siguiente elemento en la iteracin. El mtodo remove() quita el ltimo elemento retornado
por next() de la coleccin subyacente. El mtodo remove puede ser llamado una sola vez por cada
llamada a next(), y arrojar una excepcin si esta regla es violada. Este mtodo remove() es la nica
forma segura de modificar una coleccin durante una iteracin.

Pgina 31 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Excepciones
Java incorpora en el propio lenguaje la gestin de errores. El mejor momento para detectar los errores
es durante la compilacin. Sin embargo prcticamente slo los errores de sintaxis son detectados
durante este periodo. El resto de problemas surgen durante la ejecucin de los programas. En el
lenguaje Java, una Exception es un cierto tipo de error o una condicin anormal que se ha producido
durante la ejecucin de un programa.
Algunas excepciones son fatales y provocan que se deba finalizar la ejecucin del programa. En este
caso conviene terminar ordenadamente y dar un mensaje explicando el tipo de error que se ha
producido. Otras, como por ejemplo no encontrar un fichero en el que hay que leer o escribir algo,
pueden ser recuperables. En este caso el programa debe dar al usuario la oportunidad de corregir el
error (indicando una nueva localizacin del fichero no encontrado, por ejemplo).
Un buen programa debe gestionar correctamente todas o la mayor parte de los errores que se pueden
producir. Hay dos estilos de hacer esto:
1. A la antigua usanza: los mtodos devuelven un cdigo de error. Este cdigo se chequea en
el entorno que ha llamado al mtodo con una serie de if else if , gestionando de forma
diferente el resultado correcto o cada uno de los posibles errores. Este sistema resulta muy
complicado cuando hay varios niveles de llamadas a los mtodos.
2. Con soporte en el propio lenguaje: En este caso el propio lenguaje proporciona construcciones
especiales para gestionar los errores o Exceptions. Suele ser lo habitual en lenguajes
modernos, como C++, Visual Basic y Java.

Excepciones estndar de Java


Los errores se representan mediante dos tipos de clases derivadas de la clase Throwable: Error y
Exception. La siguiente figura muestra parcialmente la jerarqua de clases relacionada con
Throwable:

La clase Error est relacionada con errores de compilacin, del sistema o de la JVM. De ordinario
estos errores son irrecuperables y no dependen del programador (excepto los errores de
compilacin...) ni debe preocuparse de capturarlos y tratarlos (aunque el cdigo deber estar libre de
errores para compilarse).
La clase Exception tiene ms inters. Dentro de ella se puede distinguir:
1. RuntimeException: Son excepciones muy frecuentes, de ordinario relacionadas con errores de
programacin. Se pueden llamar excepciones implcitas.

Pgina 32 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
2. Las dems clases derivadas de Exception son excepciones explcitas. Java obliga a tenerlas
en cuenta y chequear si se producen.
El caso de RuntimeException es un poco especial. El propio Java durante la ejecucin de un programa
chequea y lanza automticamente las excepciones que derivan de RuntimeException. El programador
no necesita establecer los bloques try/catch para controlar este tipo de excepciones.
Representan dos casos de errores de programacin:
1. Un error que normalmente no suele ser chequeado por el programador, como por ejemplo
recibir una referencia null en un mtodo.
2. Un error que el programador debera haber chequeado al escribir el cdigo, como sobrepasar
el tamao asignado de un array (genera un IndexOutOfBoundsException automticamente).
En realidad sera posible comprobar estos tipos de errores, pero el cdigo se complicara
excesivamente si se necesitara chequear continuamente todo tipo de errores (que las referencias sean
distintas de null, que todos los argumentos de los mtodos sean correctos, y un largo etctera).
Las clases derivadas de Exception pueden pertenecer a distintos packages de Java. Algunas
pertenecen a java.lang (Throwable, Exception, RuntimeException, ); otras a java.io
(EOFException, FileNotFoundException, ...) o a otros packages. Por heredar de Throwable todos
los tipos de excepciones pueden usar los mtodos siguientes:

String getMessage(): Extrae el mensaje asociado con la excepcin.


String toString(): Devuelve un String que describe la excepcin.
void printStackTrace(): Indica el mtodo donde se lanz la excepcin.

Lanzar una Exception


Cuando en un mtodo se produce una situacin anmala, podemos lanzar nosotros explcitamente una
excepcin. El proceso de lanzamiento de una excepcin es el siguiente:
1. Se crea un objeto Exception de la clase adecuada.
2. Se lanza la excepcin con la sentencia throw seguida del objeto Exception creado.
// Cdigo que lanza la excepcin MyException una vez detectado el error
MyException me = new MyException("MyException message");
throw me;
Esta excepcin deber ser capturada (atrapada, del ingls "to catch") y gestionada en el propio
mtodo o en algn otro lugar del programa (en otro mtodo anterior en la pila o stack de llamadas).
Al lanzar una excepcin el mtodo termina de inmediato, sin devolver ningn valor. Solamente en el
caso de que el mtodo incluya los bloques try/catch/finally se ejecutar el bloque catch que la
captura y, si existiese, el bloque finally.
Todo mtodo en el que se puede producir uno o ms tipos de excepciones (y que no utiliza
directamente los bloques try/catch/finally para tratarlos) debe declarar en el encabezado qu
excepciones puede lanzar por medio de la palabra throws. Si un mtodo puede lanzar varias
excepciones, se ponen detrs de throws separadas por comas, como por ejemplo:
public void leerFichero(String fich) throws EOFException,
FileNotFoundException {}
Alternativamente, se puede poner nicamente una superclase de excepciones para indicar que se
pueden lanzar excepciones de cualquiera de sus clases derivadas. El caso anterior sera equivalente a:
public void leerFichero(String fich) throws IOException {}

Pgina 33 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Las excepciones pueden ser lanzadas directamente por leerFichero() o por alguno de los mtodos
llamados por leerFichero().

Capturar una Exception


Como ya se ha visto, ciertos mtodos de los packages de Java y algunos mtodos creados por
cualquier programador producen (lanzan) excepciones. Si el usuario llama a estos mtodos sin
tenerlo en cuenta se produce un error de compilacin con un mensaje del tipo: Exception
java.io.IOException must be caugth or it must be declared in the throws clause of this method o bien
"Unhandled exception". El programa no compilar mientras el usuario no haga una de estas dos
cosas:
1. Gestionar la excepcin con una construccin del tipo try {} catch {}.
2. Re-lanzar la excepcin hacia un mtodo anterior en el stack, declarando que su mtodo
tambin lanza dicha excepcin, utilizando para ello la construccin throws en el header del
mtodo.
El compilador obliga a capturar las llamadas "excepciones explcitas", pero no protesta si se captura y
luego no se hace nada con ella. En general, es conveniente por lo menos imprimir un mensaje
indicando qu tipo de excepcin se ha producido.

Bloques try / catch


En el caso de las excepciones que no pertenecen a las RuntimeException y que por lo tanto Java
obliga a tenerlas en cuenta habr que utilizar el bloque try/catch/finally. El cdigo dentro del
bloque try est vigilado: Si se produce una situacin anormal y se lanza por lo tanto una excepcin
el control salta o sale del bloque try y pasa al bloque catch, que se hace cargo de la situacin y
decide lo que hay que hacer.
Se pueden incluir tantos bloques catch como sean necesarios, cada uno de los cuales tratar un tipo
de excepcin.
Las excepciones se pueden capturar individualmente o en grupo, por medio de una superclase de la
que deriven todas ellas.
El bloque finally es opcional. Si se incluye sus sentencias se ejecutan siempre, sea cual sea la
excepcin que se produzca o si no se produce ninguna. El bloque finally se ejecuta aunque en el
bloque try haya un return. En el siguiente ejemplo se presenta un mtodo que debe "controlar" una
IOException relacionada con la lectura de ficheros y una MyException propia:
void metodo1(){
...
try {
// Cdigo que puede lanzar las excepciones IOException y
// MyException
} catch (IOException e1) {
// Se ocupa de IOException simplemente dando aviso
System.out.println(e1.getMessage());
} catch (MyException e2) {
// Se ocupa de MyException dando un aviso y finalizando la
// funcin
System.out.println(e2.getMessage());
return;
} finally {
// Sentencias que se ejecutarn en cualquier caso

Pgina 34 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
...
}
...
} // Fin del metodo1
Puede existir un bloque try sin bloques catch. En este caso se debe incluir un bloque finally para
que se pueda compilar. Esta situacin se presenta cuando dentro del bloque try ningn mtodo puede
lanzar excepciones explcitas pero s implcitas, y deseamos que en ese caso -si surge una de esas
excepciones implcitas-, se haga algo (lo que se encuentra en el bloque finally) antes del abrupto
final del programa, y sin darle ningn tratamiento con bloques catch. Como se puede deducir, no es
una situacin muy comn.

Relanzar una Exception


Existen algunos casos en los cuales el cdigo de un mtodo puede generar una Exception y no se
desea incluir en dicho mtodo la gestin del error. Java permite que este mtodo pase o relance
(throws) la Exception al mtodo desde el que ha sido llamado, sin incluir en el mtodo el bloque
try/catch correspondiente. Esto se consigue mediante la adicin de throws ms el nombre de la
Exception concreta despus de la lista de argumentos del mtodo. A su vez el mtodo superior
deber incluir los bloques try/catch o volver a pasar la Exception para "arriba" en la pila de
llamadas. De esta forma se puede ir pasando la Exception de un mtodo a otro hasta llegar al ltimo
mtodo del programa, el mtodo main().
El ejemplo anterior (metodo1) realizaba la gestin de las excepciones dentro del propio mtodo. Ahora
se presenta un nuevo ejemplo (metodo2) que relanza las excepciones al siguiente mtodo:
void metodo2() throws IOException, MyException {
...
// Cdigo que puede lanzar las excepciones IOException y MyException
...
} // Fin del metodo2
Segn lo anterior, si un mtodo llama a otros mtodos que pueden lanzar excepciones explcitas, tiene
dos posibilidades:
1. Capturar las posibles excepciones y gestionarlas.
2. Capturar las posibles excepciones y remitirlas hacia el mtodo que llam al mtodo actual.
Si no hace ninguna de las dos cosas anteriores el compilador da un error. Si en vez de tratarse de
excepciones explcitas se tratase de excepciones implcitas, el compilador no avisar de nada y el
programa se compilar sin problemas. En caso de producirse una excepcin, el programa aborta la
ejecucin sin que podamos controlar nada.

Bloque finally {...}


El bloque finally {...} debe ir detrs de todos los bloques catch considerados. Si se incluye (ya
que es opcional) sus sentencias se ejecutan siempre, sea cual sea el tipo de excepcin que se
produzca, o incluso si no se produce ninguna. El bloque finally se ejecuta incluso si dentro de los
bloques try/catch hay una sentencia continue, break o return. La forma general de una seccin
donde se controlan las excepciones es:
try {

Pgina 35 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
// Cdigo vigilado que puede lanzar una excepcin de tipo A, B o C
} catch (A a1) {
// Se ocupa de la excepcin A
} catch (B b1) {
// Se ocupa de la excepcin B
} finally {
// Sentencias que se ejecutarn en cualquier caso
}
El bloque finally es necesario en los casos en que se necesite recuperar o devolver a su situacin
original algunos elementos. No se trata de liberar la memoria reservada con new ya que de ello se
ocupar automticamente el garbage collector.
Como ejemplo se podra pensar en un bloque try dentro del cual se abre un fichero para lectura y
escritura de datos y se desea cerrar el fichero abierto. El fichero abierto se debe cerrar tanto si
produce una excepcin como si no se produce, ya que dejar un fichero abierto puede provocar
problemas posteriores. Para conseguir esto se deber incluir las sentencias correspondientes a cerrar
el fichero dentro del bloque finally.

Crear nuevas excepciones


El programador puede crear sus propias excepciones slo con heredar de la clase Exception o de una
de sus clases derivadas. Lo lgico es heredar de la clase de la jerarqua de Java que mejor se adapte
al tipo de excepcin. Las clases Exception suelen tener dos constructores:
1. Un constructor sin argumentos.
2. Un constructor que recibe un String como argumento. En este String se suele definir un
mensaje que explica el tipo de excepcin generada. Conviene que este constructor llame al
constructor de la clase de la que deriva mediante super(String).
Al ser clases como cualquier otra se podran incluir variables y mtodos nuevos. Por ejemplo:
class MiExcepcion extends Exception {
public MiExcepcion() { // Constructor por defecto
super();
}
public MiExcepcin(String s) { // Constructor con mensaje
super(s);
}
}

Herencia de clases y tratamiento de excepciones


Si un mtodo redefine otro mtodo de una super-clase que utiliza throws, el mtodo de la clase
derivada no tiene obligatoriamente que poder lanzar todas las mismas excepciones de la clase base.
Es posible en el mtodo de la subclase lanzar las mismas excepciones o menos, pero no se pueden
lanzar ms excepciones. No puede tampoco lanzar nuevas excepciones ni excepciones de una clase
ms general. Se trata de una restriccin muy til ya que como consecuencia de ello el cdigo que
funciona con la clase base podr trabajar igualmente con referencias de clases derivadas,
respetndose de esta manera el polimorfismo.

Pgina 36 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

JDBC
JDBC (Java DataBase Connectivity) es el framework provisto por Java para conectarse a bases de
datos. La idea es independizar esta comunicacin del motor puntual, brindando una interfaz comn. A
continuacin veremos las caractersticas ms bsicas de la interfaz del desarrollador del API JDBC.
Esto es, la parte del API que un desarrollador Java, dado un manejador para una determinada base de
datos, necesita para interactuar con la base de datos. Esta parte del API permite al desarrollador
realizar tres tareas:
1. Establecer una conexin con una base de datos
2. Enviar una consulta SQL a la base de datos
3. Procesar los resultados de la consulta.
El API JDBC del desarrollador de aplicaciones consta de dos partes, por un lado est el paquete
java.sql, que contiene las clases e interfaces que permiten acceder a la funcionalidad bsica del API
JDBC. Este paquete forma parte de la edicin estndar de la plataforma Java (J2SE), desde la versin
1.1 de sta. Por otro lado estn las clases e interfaces del paquete javax.sql, que forma parte de la
edicin empresarial de plataforma Java (J2EE), las que no sern vistas en este mdulo.

Los manejadores
Los manejadores, tambin llamados drivers, son un conjunto de clases que implementan las clases e
interfaces del API JDBC necesarias para que una aplicacin Java pueda conectarse con una BD.
Cuando los desarrolladores de una BD desean que esta pueda ser accesible mediante JDBC stos
deben implementar un manejador para esa base de datos; la misin del manejador ser traducir
comandos estndar del API JDBC al protocolo nativo de esa base de datos.
Cada base de datos emplea un protocolo diferente de comunicacin, protocolos que normalmente son
propietarios. El uso de un manejador, una capa intermedia entre el cdigo del desarrollador y la base
de datos, permite independizar el cdigo Java que accede a la BD del sistema de BD concreto a la que
estamos accediendo, ya que en nuestro cdigo Java emplearemos comandos estndar, y estos
comandos sern traducidos por el manejador a comandos propietarios de cada sistema de BD
concreto. Si queremos cambiar el sistema de BD que empleamos lo nico que deberemos hacer es
reemplazar el antiguo manejador por el nuevo, y seremos capaces de conectarnos la nueva BD.

Tipos de manejadores
Hay 4 tipos de manejadores JDBC, que difieren en si usan o no tecnologa Java pura, en su
rendimiento y en la flexibilidad para cambiar de base de datos. Veamos cuales son:
Puente JDBC-ODBC (tipo1)
ODBC es un API estndar semejante a JDBC, que permite que lenguajes como C++ accedan de un
modo estndar a distintos sistemas de BD. Un manejador tipo puente JDBC-ODBC delega todo el
trabajo sobre un manejador ODBC, que es quien realmente se comunica con la BD. El puente JDBCODBC permite la conexin desde Java a bases de datos que no proveen manejadores JDBC. Fue muy
til cuando se cre el API JDBC, ya que muchas BD no disponan de manejadores JDBC, pero s de
manejadores ODBC. Empleando el puente JDBC-ODBC poda accederse a estas bases de datos
empleando el API JDBC. Este tipo de manejador tiene dos desventajas: por un lado depende de cdigo
nativo, ya que el manejador ODBC no ha sido desarrollado en Java. Esto compromete la portabilidad
de nuestro desarrollo. Por otro lado al emplear este tipo de manejador nuestra aplicacin llama al

Pgina 37 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
gestor de manejadores JDBC, quien a su vez llama al manejador JDBC (puente JDBC-ODBC), quien
llama al manejador ODBC, que es el que finalmente llama a la base de datos. Hay muchos puntos
donde potencialmente puede producirse un fallo, lo cual hace que estos manejadores muchas veces
sean bastante inestables.

El puente forma parte del jdk de SUN, est en el paquete sun.jdbc.odbc. Inicialmente este tipo de
manejador fue bastante til por aliviar la carencia de manejadores JDBC. Hoy en da es el menos
recomendado por limitar la portabilidad de la aplicacin, al requerir cdigo nativo, y por emplear
tantas capas para la comunicacin con la base de datos, lo que a veces hace que se incremente la
inestabilidad de estos manejadores.
Manejador nativo (tipo2)
Se basa en una biblioteca escrita en cdigo nativo para acceder a la base de datos. El manejador
traduce las llamadas JDBC a llamadas al cdigo de la librera nativa, siendo el cdigo nativo el que se
comunica con las bases de datos. La librera nativa es proporcionada por los desarrolladores de la BD.
Estos manejadores son ms eficientes y tienen menos puntos de fallo que el puente JDBC-ODBC ya
que hay menos capas entre el cdigo de la aplicacin y la base de datos. Sin embargo siguen teniendo
el problema de prdida de portabilidad por emplear cdigo nativo.

Pgina 38 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Manejador de JDBC-Net (tipo3)


El manejador se comunica con un servidor intermedio que se encuentra entre el cliente y la base de
datos. El servidor intermediario se encarga de traducir las llamadas del API JDBC al protocolo
especfico de la base de datos.
No se requiere ningn tipo de cdigo nativo en el cliente, por lo que la portabilidad de la aplicacin
est garantizada: el manejador es tecnologa 100% Java. Adems, si el intermediario es capaz de
traducir las llamadas JDBC a protocolos especficos de diferentes sistemas de BD podremos emplear
un mismo manejador para comunicarnos con diferentes bases de datos. Esto lo convierte en el
manejador ms flexible de todos.
No obstante se trata de un driver complejo, ya que requiere la presencia de un middleware, una capa
intermedia entre el cliente y la base de datos, por lo que no es muy comn emplearlo en arquitecturas
simples, sino ms bien en arquitecturas sofisticadas donde muchas veces entran en juego varias bases
de datos distintas.

Pgina 39 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Manejador Java (tipo4)


El manejador traduce directamente las llamadas al API JDBC al protocolo nativo de la base de datos.
Es el manejador que tiene mejor rendimiento, pero est ms ligado a la base de datos que empleemos
que el manejador tipo JDBC-Net, donde el uso del servidor intermedio nos da una gran flexibilidad a la
hora de cambiar de base de datos. Este tipo de manejadores tambien emplea tecnologa 100% Java.

El API de JDBC, paquete java.sql

Pgina 40 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Clase DriverManager
Como su nombre indica esta clase es la gestora de los diversos drivers (manejadores) que haya en
nuestra aplicacin. Es posible que sea necesario en una misma aplicacin tener varios manejadores
para una misma base de datos, acceder a varias bases de datos que emplean distintos manejadores, o
bien ambas situaciones a la vez. De ah el inters de contar con este gestor de manejadores.
Los mtodos que ms nos interesan de esta clase son
static Connection getConnection(String url) y
static Connection getConnection(String url, String user, String password)
Estos mtodos intentan establecer conexin con la base de datos que le indiquemos en el campo url
empleando para ellos todos los manejadores que hemos registrado. La diferencia entre un mtodo y el
otro, obviamente, es que en uno slo se especifica la base de datos a la que nos queremos conectar,
mientras que en el otro se indica tambin el nombre de usuario de la base de datos y su password.
Ms adelante explicaremos que es el objeto Connection que devuelven estos mtodos.
Lo que hace la clase DriverManager para intentar establecer conexin con la base de datos es invocar
al mtodo connect de la interface Driver, interface que como veremos deben implementar todos los
manejadores. Esta operacin se realizar con todos los manejadores que estn registrados; si el
manejador devuelve null significa que no se ha podido conectar con la base de datos; entonces el
gestor intenta de nuevo conectarse con otro manejador. Si consigue conectarse con un manejador no
sigue intentndolo con el resto de los manejadores registrados, y si no consigue establecer la
conexin con ningn manejador lanza una excepcin tipo SQLException.

Pgina 41 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Sintaxis de los URL de JDBC


Los URL (Uniform Resource Locator) de JDBC identifican una base de datos, y un protocolo de
conexin a esta, de un modo unvoco. Toda URL de JDBC consta siempre de tres partes:
protocolo:subprotocolo:subnombre.
Un ejemplo de URL de conexin podra ser: jdbc:odbc:usuarios. Veamos qu es cada una de las
partes del URL:
1. Protocolo de la conexin. Siempre es jdbc.
2. Subprotocolo de la conexin. Identifica el tipo de mecanismo de conexin que emplearemos
para acceder a la base de datos. Es imprescindible especificarlo para que el DriverManager
pueda saber qu tipo de manejador debe emplear para crear la conexin. En el URL ejemplo el
subprotocolo empleado para la conexin a la base de datos ser ODBC, por lo que el
DriverManager intentar establecer la conexin con todos los manejadores registrados que
sean de tipo 1, puente JDBC-ODBC.
3. Subnombre, identifica la base de datos con la que queremos establecer una conexin. En el
ejemplo el subnombre es clientes; ser el sistema ODBC quien proporcione, a partir de ese
nombre, el resto de la informacin necesaria para establecer la conexin con la base de datos.
Sin embargo si empleamos otro protocolo puede ser necesario incluir la direccin de red del
servidor como subnombre. As por ejemplo para conectar con una base de datos remota la
sintaxis de la URL es:
protocolo:subprotocolo://servidor:puerto/subnombre

Pgina 42 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
As por ejemplo la URL: jdbc:bdnet://kwcserver:4040/usuarios Empleara el protocolo jdbc y un
manejador de tipo JDBC-Net para conectarse a la hipottica base de datos usuarios a travs del
puerto 4040 de la mquina kwcserver.
Registro de un manejador
Registrar un manejador no es ms que cargar en memoria una clase que implementa el interfaz
Driver, clase proporcionada por los desarrolladores de la base de datos. Existen tres formas de
registrar un driver:
1. Empleando el cargador de clases. Para ello empleamos, al igual que para cargar cualquier otra
clase, el mtodo forName(String clase) de la clase Class.
Class.forName("com.mysql.Driver");
2. Instanciando la clase que implementa el interfaz Driver. De este modo tendremos una
referencia al driver, pudiendo establecer la conexin directamente con l sin necesidad de
emplear la clase DriverManager. La sintaxis es la misma que para instanciar cualquier otra
clase:
Driver driverPraMySQL = new com.mysql.jdbc.Driver();
3. Definir la propiedad jdbc.drivers. Podemos hacerlo de dos modos diferentes:
a. Definiendo la propiedad jdbc.drivers en nuestra mquina virtual. La sintaxis es:
jdbc.drivers=nombreManejador1: nombreManejador2:
jdbc.drivers=gjt.mm.mysql.Driver:oracle.jdbc.driver.OracleDriver;
b. Emplear la opcin D al invocar a la mquina virtual. Para ello debemos arrancar
nuestra aplicacin con el comando
java -Djdbc.drivers=nombreManejador1: nombreManejador2:
java -Djdbc.drivers=gjt.mm.mysql.Driver:oracle.jdbc.driver.OracleDriver;
Interfaz Driver
Aunque es vital para establecer la conexin con la base de datos en la prctica el desarrollador de
aplicaciones puede olvidarse de esta interfaz. Es responsabilidad del desarrollador del manejador
proveer una clase que implemente esta interfaz, y ser responsabilidad del DriverManager llamar al
mtodo connect de los drivers registrados para intentar establecer la conexin con la base de datos.
No obstante es, posible crear un objeto tipo Driver -instanciando la clase desarrollada por el
desarrollador del manejador- e invocar directamente a su mtodo connect, obteniendo una conexin
con la base de datos sin necesidad de emplear la clase DriverManager. De este modo tenemos ms
control sobre el driver que estamos empleando en la conexin, cuando hemos registrado ms de un
driver, ya que no nos arriesgamos a que se establezca conexin con la BD con un driver distinto al que
nosotros deseamos usar.
Interfaz Connection
Representa una conexin con la base de datos. Permite crear objetos que representan consultas que
se ejecutarn en la base de datos, y permite acceder a informacin sobre la base de datos y las
posibilidades del manejador JDBC.
En la tabla recogemos los principales mtodos de la interfaz Connection.
void close()
void commit()
Statement
createStatement()

Libera lo los recursos de esta conexin.


Hace permanentes los cambios que se
realizaron desde el ltimo commit o rollback.
Crea un objeto de tipo Statement.

Pgina 43 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
boolean getAutoCommit()
DatabaseMetaData getMetaData()

Indica si est en modo auto-commit.


Devuelve un objeto tipo DatabaseMetaData
con meta informacin a cerca de la base de
datos contra la cual se ha abierto esta
conexin.
CallableStatement prepareCall(String
Crea un objeto CallableStatement para
sql)
ejecutar procedimientos almacenados SQL en
la BD.
PreparedStatement prepareStatement
Crea un objeto PreparedStatement para
(String sql)
ejecutar consultas SQL parametrizadas en la
BD.
void rollback()
Deshace todos los cambios realizados desde la
ltima vez que se ejecut comit o rollback
void setAutoCommit (boolean autoCommit) Indica el modo de commit en el cual se opera.

Interfaz Statement
Esta interfaz permite enviar instrucciones SQL a la base de datos. Podemos obtener un objeto que
implemente esta interfaz a partir del mtodo Statement createStatement() de la interfaz
Connection. Para enviar una consulta tipo SELECT se emplea el mtodo execteQuery(String sql).
Este mtodo devuelve un objeto tipo Resultset. Para enviar una instruccin tipo DELETE, UPDATE,
INSERT o una instruccin DDL (Data Definition Language) se emplea executeUpdate(String sql).
Mediante el mtodo execute(String sql) podemos ejecutar cualquiera de los comandos anteriores.
El mtodo execute devuelve un booleano indicando si hay ResultSet o no. En caso de haberlo, se lo
puede recuperar con el mtodo getResultSet(). El mtodo executeUpdate devuelve un entero
indicando la cantidad de registros afectados. Y el mtodo executeQuery devuelve un ResultSet.
Interfaz PreparedStatement
Representa una instruccin SQL preparada, esto es, una instruccin SQL precompilada cuya ejecucin
es mucho ms eficiente que ejecutar repetidas veces una misma instruccin SQL. Cuando vayamos a
ejecutar varias veces las mismas instrucciones debemos emplear esta interfaz.
Podemos obtener un objeto que implemente esta interfaz a partir del mtodo PreparedStatement
createPreparedStatement(String sql) de la interfaz Connection. La interfaz PreparedStatement
extiende a Statement aadiendo una serie de mtodos setXXX(int indice, XXX valor) que
permiten, para cada ejecucin de la instruccin, asignar un valor a los parmetros de la instruccin
SQL precompilada (los parmetros comienzan de 1). El primer valor, siempre un entero, es el ndice
del parmetro al cual le vamos a asignar un valor, empezando a contar en 1, y valor es el valor que
le asignamos a ese parmetro.
Interfaz CallableStatement
Permite ejecutar procedimientos almacenados. Extiende a la interfaz PreparedSatatement. Podemos
obtener un objeto que implemente esta interfaz a partir del mtodo CallableStatement
prepareCall(String sql) de la interfaz Connection.
Los parmetros de entrada (o de entrada-salida) del procedimiento almacenado deben ser setados con
los mtodos set heredados de PreparedStatement. Los parmetros de salida (o los de entradasalida) deben ser registrados (con su correspondiente tipo) antes de la ejecucin mediante el mtodo
registerOutParameter().

Pgina 44 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Luego de la ejecucin, los parmetros de salida se pueden obtener a travs de mtodos get. Tambin
pueden obtenerse uno o ms objetos ResultSet.
Interfaz ResultSet
Esta interfaz representa un conjunto de datos que son el resultado de una consulta SQL. La clase
posee una serie de mtodos XXX getXXX(int columna) y XXX getXXX(String columna) que
permiten acceder a los resultados de la consulta (para la sintaxis concreta de estos mtodos acudir al
javadoc de la interfaz ResultSet). La diferencia entre el primer tipo y el segundo es que en el primero
usamos ordinales de columnas (empezando desde 1) mientras que en el segundo usamos nombres de
columnas. Para acceder a los distintos registros empleamos un cursor, que inicialmente apunta justo
antes de la primera fila. Para desplazar el cursor empleamos el mtodo next().

Una aplicacin JDBC bsica


Toda aplicacin que acceda a una base de datos empleando el API JDBC debe realizar una serie de
pasos:
1.
2.
3.
4.

Establecer una conexin con la base de datos.


Ejecutar una o varias instrucciones SQL
Si las intrusiones devuelven datos (SELECT) debemos procesarlos.
Liberar los recursos de la conexin.

Conectndose a la base de datos


En un primer lugar debemos de registrar el o los manejadores que queramos emplear para acceder a
la base de datos. Para ello debemos asegurarnos que el archivo .jar que contiene los drivers de
nuestra base de datos est incluido en el CLASSPATH que emplea nuestra mquina virtual.
Para registrar el manejador podemos emplear cualquiera de los procedimientos ya vistos. En este
cdigo se ha empleado el cargador de clases:
Class.forName(String driver).
Para establecer la conexin emplearemos el mtodo getConection de la clase
DriverManager.

Pgina 45 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

String driver = "com.mysql.jdbc.Driver";


String url = "jdbc:mysql://kwcserver:3306/mydb";
Connection conexion = null;
try {
//Registramos el manejador
Class.forName(driver);
//Establecemos una conexin con la base de datos
conexion = DriverManager.getConnection(url, "user", "pwd");
...
Ejecutar las instrucciones SQL
Para ejecutar las instrucciones SQL debemos crear un objeto tipo Statement,
PreparedStatement o CallableStatement, dependiendo de si queremos ejecutar SQL, SQL
precompilado o instrucciones no-SQL (procedimientos almacenados). Para ello empleamos los
mtodos definidos con tal propsito en la interface Connection.
En nuestro caso ser un objeto tipo Statement:
Statement st = conexion.createStatement().
A continuacin ejecutamos las instrucciones SQL, empleando los mtodos executeUpdate(String
sql) para instrucciones tipo UPDATE, DELETE, INSERT o instrucciones DDL. Para las instrucciones de
tipo SELECT empleamos el mtodo Resultset executeQuery(String sql).
En este caso primero se ejecuta una instruccin DDL, en la que se define una nueva tabla en la base
de datos, a continuacin creamos una serie de registros en la tabla, y finalmente realizamos una
consulta en la cual pedimos el campo NOMBRE de todos los registros cuyo campo
NIVEL_PARTICIPACION sea superior a 0.5.
//Creamos un objeto Statement que nos permitir ejecutar instrucciones SQL
Statement st = conexion.createStatement();
//Ejecutamos una instruccin de DDL para crear una tabla
st.executeUpdate("create table usrs " +
"(NOMBRE varchar(25), " +
"LOGIN varchar(15)," +
"EDAD int, " +
"NIVEL_PARTICIPACION float)");
//Insertamos un grupo de registros en la tabla
st.executeUpdate( "insert into usuarios values('Pepe','pepe',23,
0.64)");

//Ejecutamos una consulta


Resultset resultset = st.executeQuery("select NOMBRE from usrs "+
"where NIVEL_PARTICIPACION > 0.5");

Procesar los resultados


Tras realizar una consulta tipo SELECT obtenemos como resultado un conjunto de registros, a los
cuales podemos acceder mediante la interface Resultset. Esta provee una serie de mtodos
getXXX(columna) que permiten acceder a cada campo de cada registro devuelto como respuesta a
nuestra consulta. Es importante conocer a qu tipo Java se corresponde cada tipo SQL para saber
mediante qu mtodo debemos acceder al contenido de cada columna.

Pgina 46 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
La correspondencia entre tipos de datos Java y tipos de datos SQL se muestra en la siguiente tabla:
Tipo Java
boolean
byte
short
int
long
float
double
java.math.BigDecimal
String
byte[]
java.sql.Date
java.sql.Time
java.sql.Timestamp

Tipo SQL
BIT
TINYINT
SMALLINT
INTEGER
BIGINT
REAL
DOUBLE
NUMERIC
VARCHAR o LONGVARCHAR
VARBINARY o LONGVARBINARY
DATE
TIME
TIMESTAMP

Debemos tener en cuenta siempre que cada objeto Resultset est ligado al objeto Statement que lo
gener, y al objeto Connection de donde se obtuvo ese Statement. Por esto, si tenemos un objeto
Resultset y ejecutamos una sentencia tipo SELECT con el Statement que lo haba generado, los
resultados de la anterior consulta se perdern, al igual que si la conexin a la base de datos se cierra.
// Mientras queden resultados por procesar.
// Recuerde que next() desplaza el cursor del Resulset una
// posicin hacia delante cada vez que se invoca.
while (resultset.next()) {
// Accedemos a los resgistros resultado mediante los mtodos
// getXXXX Indicando el nombre de la columna
System.out.println(resultset.getString("NOMBRE")+
", gracias por ser un usuario tan activo !");
}
Liberar los recursos de la conexin
Una vez que hayamos terminado las operaciones que queramos realizar en la base de datos debemos
liberar todos los recursos que estaba consumiendo la conexin. Aunque estos recursos son
automticamente liberados por el GarbageCollector cuando sus correspondientes objetos son
eliminados, es buena practica liberarlos manualmente, para que esta liberacin se produzca en cuanto
dejan de ser tiles.
Los recursos que debemos liberar son el Resultset, el Statement y la propia conexin. Para liberarlos
debemos invocar al mtodo close() de sus correspondieres objetos. Invocar al mtodo close() de
Statement automticamente libera los recursos de su ResultSet.
// No nos olvidemos de liberar todos los recursos que hemos empleado una
// vez que no necesitemos la conexin: debemos liberar tanto los recursos
// consumidos por el Resulset, por los Statement empleados y las propias
// Conexiones
try {
resultset.close();
statement.close();
conexion.close();
}catch(SQLException e){}

Pgina 47 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

Gestin de excepciones JDBC


Todos los mtodos definidos en las interfaces Connection, Statement y ResultSet, as como el
mtodo
getConnection()
de
la
clase
DriverManager
lanzan
excepciones
de
tipo
java.sql.SQLException, por lo que todo el cdigo que de uno u otro modo acceda a la base de datos
o procese los resultados de un acceso ha de estar dentro de una clausula try/catch, o bien ha de
estar dentro de un mtodo que lance excepciones de tipo SQLException.
La Clase SQLException
La excepcin SQLException tiene algunas caractersticas que la diferencian del resto de las
excepciones. Ms que una excepcin propiamente dicha, es una lista de excepciones encadenadas.
Muchos y muy distintos problemas pueden suceder en el servidor, y no sera fcil almacenar toda la
informacin correspondiente a todos los problemas en una nica excepcin. Por ello la clase
SQLException ha sido diseada como una cadena de Excepciones, permitiendo almacenar informacin
de todos los errores surgidos en la operacin. Esta clase tiene un mtodo, getNextException(), que
nos devuelve la siguiente excepcin de la cadena , o null si no hay ms excepciones encadenadas. El
cdigo que mostramos a continuacin permite imprimir un cdigo de error del fabricante de la base de
datos, el mensaje de error, y la traza de todas las excepciones encadenadas en una SQLException
catch (SQLException e) {
do{
System.out.println(e.getErrorCode());
System.out.println(e);
e.printStackTrace();
e = e.getNextException();
}while (e != null);
}
Las principales causas de que se produzcan excepciones SQL son:
1. Se pierde la conexin con la base de datos. Muchas cosas pueden ir mal cuando la base de
datos es remota y se accede a ella a travs de la red.
1. Se enva un comando SQL no vlido; por ejemplo, tecleamos wehere en vez de where. En
este sentido resulta muy til probar el SQL empleando alguna interfaz grfica de nuestra base
de datos antes de empotrarlo en el cdigo Java.
2. Se hace referencia a una columna o tabla que no existen
3. Se emplea una funcin que no est soportada por la base de datos.
La clase SQLWarning
Es una subclase de SQLException. Un SQLWarning se genera cuando se produce un error no fatal en
la base de datos. Se encadenan igual que las excepciones SQL, pudiendo acceder al siguiente
SQLWarning de la cadena mediante el mtodo getNextWarning().
A diferencia que las excepciones los warning no se lanzan, cuando queramos acceder a ellos
deberemos emplear el mtodo getWarnings(), que est definido en las interfaces Connection,
Statment y Resultset.

Metainformacin

Pgina 48 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
El API JDBC nos permite acceder a metainformacin sobre la base de datos y sobre el ResultSet
generado por una consulta, es decir, a informacin a cerca de las caractersticas (no del contenido) de
la base de datos y del Resultset, informacin como el nombre de la base de datos, la versin, el
nmero y nombre de las columnas del Resultset, etc.
La metainformacin de la base de datos est representada por un objeto que implementa la interfaz
java.sql.DatabaseMetaData, objeto al cual nos da acceso el mtodo getMetaData() de la interface
Connection. En DatabaseMetaData hay, por ejemplo mtodos como getDriverName(), que nos
devuelve el nombre del driver que estamos empleando, getDriverVersion(), que nos devuelve la
versin del driver, getDatabaseProductName(), el nombre de la base de datos, getURL(), la URL de
esta base de datos, etc.
La metainformacin del ResultSet est representada por un objeto que implementa la interfaz
ResultSetMetaData, accesible mediante el mtodo getMataData() de la interfaz ResultSet. En esta
interfaz tenemos mtodos para, por ejemplo, averiguar el nmero de columnas del ResultSet
getColumnCount(), el nombre de cada columna, getColumnName(int columna), saber si podemos
escribir en una columna, isWritable(int columna), clase Java correspondiente a una columna,
getColumnClassName(int columna), etc.
En este cdigo se accede a la metainformacin del ResultSet para averiguar el nmero y nombre de
las columnas, y se imprime una tabla en la consola con el resultado.
public static void imprimeConsulta(ResultSet resultSet) {
try {
//Obtenemos la Metainformacin de ResulSet
ResultSetMetaData resultSetMetaData =
resultSet.getMetaData();
//A partir de la metainformacin obtenemos el nmero de
//columnas
int numeroDeColumnas =
resultSetMetaData.getColumnCount();
//Para todas las columnas
for (int i = 1; i <= numeroDeColumnas; i++) {
//Averguamos cual es el nombre de cada columna
String nombreDeLaColumna =
resultSetMetaData.getColumnName(i);
stringBuffer.append(nombreDeLaColumna + "\t");
}
//Ahora recorremos el resulset igual que en el primer ejemplo
while (resultSet.next()) {
//Accedemos a todas las columnas del registro
for (int i = 1; i <= numeroDeColumnas; i++) {
//Acedemos a todas como String, aunque empleando la
//metainformacin sera posible averiguar que tipo de dato es
stringBuffer.append(resultSet.getString(i) + "\t");
}
}
System.out.println(stringBuffer.toString());
}

Transacciones
Una transaccin es un conjunto de operaciones que deben de realizarse de un modo atmico sobre la
base de datos, esto es, o bien se realizan todas ellas correctamente, o bien no se realiza ninguna. Las
transacciones son importantes para mantener la consistencia de la informacin en la base de datos.

Pgina 49 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Imaginemos que tenemos un registro en la tabla usuario, la clave primaria de este registro es
referenciada por un registro en una tabla llamada pedidos. Borrar a ese usuario implica borrar los
pedidos que haya hecho ese usuario; en este caso podemos hacerlo con dos instrucciones DELETE,
una sobre el registro del usuario y la otra sobre el pedido. Si la primera instruccin tiene xito, y la
segunda no, en la base de datos tendremos un pedido que referencia a un usuario que no existe. Para
evitar este problema podemos agrupar las dos operaciones de borrado en una misma transaccin; de
ese modo o eliminamos ambos registros o no eliminados ninguno. En cualquier caso la informacin de
la base de datos ser consistente.
Para emplear transacciones con el API JDBC debemos invocar el mtodo setAutocommit(false) de la
interfaz Connection. Por defecto la interfaz Connection ejecuta un commit, es decir, una confirmacin
de los cambios realizados en la base de datos, cada vez que ejecutamos una sentencia. Este mtodo
nos permite activar y desactivar este comportamiento.
A continuacin ejecutamos las operaciones que deseemos agrupar en una nica transaccin, y
finalmente, si queremos confirmar los cambios, invocamos el mtodo commit(), del interfaz
Connection. En ese momento los cambios realizados se harn permanentes en la base de datos y se
liberar cualquier tipo de bloqueo que haya realizado esta conexin.
Si queremos cancelar los cambios invocamos al mtodo rollback(), tambin de la interfaz
Connection. Este mtodo deshace todos los cambios hechos en la base de datos desde el ltimo
commit o rollback y libera cualquier tipo de bloqueo que haya realizado esta conexin. Cuando se
gestionan las excepciones del cdigo transaccional, siempre se suele poner un rollback en el catch, de
ese modo si hay un error en la ejecucin de alguna de las operaciones de la transaccin deshacemos
los cambios de las que se ejecutaron con xito.
De todas formas, cuando se desea trabajar con transacciones, lo primero a realizar es desactivar el
modo auto-commit con el mtodo setAutocommit(false), pues las conexiones son creadas por
defecto en modo auto-commit.
Control de la concurrencia
Al emplear transacciones para acceder a la base de datos pueden surgir una serie de problemas si hay
varias conexiones abiertas al mismo tiempo contra la base de datos (la base se est accediendo de
modo concurrente). Es importante conocer y entender cuales son esos problemas, as como conocer
que niveles de aislamiento transaccional nos proporciona el API JDBC para evitarlos.
Los problemas que pueden surgir son:
1. Lecturas sucias: una fila de la base de datos que ha sido modificada por una transaccin y
antes de que esta transaccin ejecute un commit (si es que finalmente llega a ejecutarse) esa
fila es leda por otra transaccin.
1. Lecturas no repetibles: una transaccin lee una fila, otra transaccin modifica esta fila y la
primera transaccin vuelve a leer la fila, pero esta vez obtiene un resultado diferente de la
primera lectura.
2. Lecturas fantasmas: una transaccin selecciona todos los registros que satisfacen una
determinada condicin, otra transaccin inserta un nuevo registro que satisface esa condicin.
La primera transaccin vuelve a seleccionar todos los registros que satisfaces la misma
condicin, pero esta vez obtiene un registro adicional, el que insert la segunda transaccin.
Control del nivel de aislamiento transaccional
El API JDBC nos permite controlar el nivel de aislamiento transaccional, esto es, cuales de los tres
problemas recogidos en el apartado anterior vamos a tolerar en nuestra conexin y cuales no. Para
ello empleamos el mtodo setTransactionIsolation(int nivel) de la interfaz Connection. El
entero que se le pasa es una variable esttica y final definida dentro de la interfaz Connection. Los
posibles valores son:

Pgina 50 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
1. Connection.TRANSACTION_NONE: Indica que la conexin no soporta transacciones. Podemos
obtener el nivel de aislamiento de una conexin mediante el mtodo getTransactionIsolation(),
si su valor es ste, significa que la conexin no soporta transacciones.
2. Connection.TRANSACTION_READ_UNCOMMITED: Permite que sucedan lecturas sucias, fantasmas
y no repetibles. Si una transaccin finalmente ejecuta un rollback() otras transacciones
pueden haber ledo informacin incorrecta.
3. Connection.TRANSACTION_READ_COMMITED: Permite que sucedan lecturas fantasmas y no
repetibles, pero no lecturas sucias.
4. Connection.TRANSACTION_REPETABLE_READ: Slo permite que sucedan lecturas fantasmas,
las lecturas sucias y no repetibles no sucedern.
5. Connection.TRANSACTION_SERIALIZABLE: Evita lecturas fantasmas, sucias y no repetibles.
Podra parecer que lo ideal es emplear siempre el mximo aislamiento transaccional, sin embargo esto
disminuye notablemente el rendimiento de la base de datos. En general el rendimiento de los accesos
a la base de datos es inversamente proporcional al nivel de asilamiento transaccional que empleemos,
por lo que debemos estudiar detenidamente que nivel trasnacional nos podemos permitir en nuestra
aplicacin.

Pgina 51 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE

J2EE
Introduccin al modelo (1.4)
J2EE es un modelo para el desarrollo de aplicaciones Java. Fue introducido por Sun en el ao 1998
como un conjunto englobador de las tecnologas de servidor Java ya existentes para la poca. O sea
que Servlets, JSPs y EJBs existan desde antes de la presentacin del modelo.
El modelo se basa en la arquitectura cliente-servidor.
Esto de "modelo" se refiere a que se est proponiendo un patrn para estructurar una aplicacin. En
ese sentido es un norte, una primera gua cuando se est diseando la arquitectura de una solucin
software. A partir de ah, cada aplicacin tiene sus particularidades, lo que hace que sean muy pocas
las que implementarn todo el modelo completo y sin alteraraciones. En el choque entre un modelo
puramente conceptual y la realidad de cada aplicacin, se sabe que no sera conveniente aplicar
exactamente el mismo patrn a todas las aplicaciones posibles. Entonces, el modelo est pensado
teniendo en cuenta esta posterior adaptabilidad al caso. Como consecuencia, en ciertos puntos se
limita a proponer la solucin ms avanzada, y en otros recurre a la tecnologa ms usada al momento
de concebirse.
Por ejemplo, podra haberse elegido seguir el modelo J2EE. Pero por el tamao de la aplicacin -dicho
de otra forma, el presupuesto-, y por la mantenibilidad requerida -para no excederse del presupuesto
se acept una mantenibilidad no ptima-, el arquitecto podra proponer implementar una aplicacin
web con Servlets y JSPs. En este caso la capa de negocio quedara a cargo de los mismos Servlets.

Capas, Componentes y Contenedores


Entonces, sabiendo que estamos en un terreno conceptual, el modelo J2EE propone la divisin de una
aplicacin en cuatro capas:

La capa de cliente: se ejecuta en la computadora del usuario final. Brinda interaccin y


dinamismo siempre que la funcionalidad no demande una comunicacin con el servidor para
obtener o guardar ms informacin.
La capa de presentacin: es la encargada de tomar las peticiones del cliente, ejecutar la
lgica de navegacin, y obtener una respuesta a dicha peticin, consultando para ello a la
capa de negocio. Una vez que se sabe la respuesta, esta capa se encarga tambin de escribirla
en el protocolo que el cliente entienda.
La capa de lgica de negocio: es la encargada de mantener las reglas del negocio. En esta
capa se encuentra el modelo de objetos del sistema, tanto objetos de entidad como objetos
gestores. Aparte de utilizarse como abreviatura de esta capa, la palabra "negocio" denomina
algo ms complejo que est en el mundo de lo social: es la organizacin que est por detrs,
que contiene al sistema de informacin, sea que aquella tenga fines de lucro o no.
La capa de datos: es la encargada de guardar los datos del negocio. De esta tarea se
encargan las bases de datos de diferentes tipos y tecnologas, por lo que el modelo no ahonda
demasiado en ella.

Cada capa est pensada para que pueda ejecutarse en computadoras diferentes. Aunque el espectro
es amplio: podramos tener ms de una capa en una misma computadora (imaginemos un servidor
web andando en una mquina y desde esa misma mquina acceder al sitio como un cliente ms); o
bien podramos tener una misma capa alojada en ms de una computadora (por ejemplo, cuando los
datos residen en ms de un servidor de bases de datos, replicndose mutuamente).

Pgina 52 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Para llevar a cabo el trabajo tendremos "componentes", que no son otra cosa que programas (objetos,
dentro del mundo Java). Estos componentes se ejecutarn en un "contenedor" apropiado. El
contenedor brinda funcionalidad al componente que aloja, al mismo tiempo que le impone
restricciones. Por ejemplo, podra encargarse de la persistencia de un bean de entidad (la persistencia
siendo el guardar y recuperar informacin del bean en una base de datos), pero ese bean de entidad
debe ajustarse a cierta versin de interfaz para que pueda ejecutarse en el contenedor.
Veamos qu componentes y contenedores se encuentran en cada capa:
Capa
Cliente

Contenedor
Client container

Presentacin

Web container

Lgica de negocio
Datos

EJB container

Contenedor includo
HTML container
Applet container
Servlet container
JSP container

Componente
HTML, JS
Applets
Servlets
JSPs
EJBs

En la capa de cliente se encuentra el "contenedor de cliente". Este contenedor suele estar


implementado en un visor HTML o browser. En l se ejecutan los archivos HTML (estos archivos ms
que ejecutarse se "pintan") con su cdigo JavaScript, y los Applets, si los hubiere.
En la capa de presentacin encontramos los componentes que toman peticiones y devuelven
respuestas desde y hacia los clientes. Esta capa puede no existir en caso de que los clientes no sean
tipo web (aqu web no significa HTTP, sino que podra usarse otro protocolo) sino que sean
aplicaciones de escritorio que se sirven directamente de los componentes del negocio.
Para la capa de la lgica de negocio, J2EE menciona que puede ser implementada con clases comunes,
con JavaBeans, o con la solucin de servidor ms avanzada: los Enterprise JavaBeans (EJBs).
Para la capa de datos, el modelo se adhiere a la tecnologa ms utilizada por el mercado: las bases de
datos relacionales. No obstante, el modelo est preparado para tomar la informacin de otras fuentes,
como pueden ser archivos de configuracin, archivos XML, bases de datos orientadas a objetos, etc.

Despliegue
El despliegue o deployment (del verbo "deploy", desplegar) es la "instalacin" de un mdulo (un
conjunto de componentes de una misma capa) en un contenedor. La aplicacin, tras haber sido
desarrollada, se comprime en un archivo con una estructura y una extensin dependientes del tipo de
mdulo de que se trate. Este archivo comprimido cuenta con un "descriptor de despliegue" o
"deployment descriptor" que indica ciertas caractersticas de la aplicacin, como los nombres JNDI
requeridos, la configuracin de seguridad, de persistencia, etc.
El mdulo web se empaqueta en un archivo .war que contiene sus componentes web (JSPs y Servlets,
ms archivos de recursos como grficos).
El mdulo EJB se empaqueta en un archivo .jar que contiene los EJBs.
Y ambos archivos (.war y .jar) se empaquetan en archivos .ear, que corresponden al mdulo de
aplicaciones de empresas. Un archivo .ear puede contener de 0 a n archivos .war, y de 0 a n archivos
.jar.
Mdulo
Aplicacin de empresa
Aplicacin Web
Aplicacin EJB

Extensin del archivo comprimido


.ear
.war
.jar

Descriptor de despliegue
application.xml
web.xml
ejb-jar.xml

Pgina 53 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Es comn que se utilice, adems del descriptor de despliegue estndar, un descriptor de despliegue
particularizado para el contenedor. Una vez ms, lo que en un principio se concibi para ser estndar,
termina "personalizndose" y rompiendo el estndar.
Lo que s es estndar es la estructura de carpetas que tiene un archivo comprimido. Pero si al
exportarse la estructura es la misma, no significa que mientras se desarrollaba los archivos hayan
estado distribuidos en carpetas idnticas. De hecho, la estructura mientras se desarrolla vara de
entorno a entorno. En la siguiente figura se muestra una comparacin entre la forma de estructurar el
proyecto segn Eclipse 3.1 y segn WebSphere 5.

Servlets
Un Servlet es un componente web, una clase que implementa la interfaz javax.servlet.Servlet. Esta
interfaz define mtodos para el ciclo de vida del programa, para obtencin de informacin del mismo,
y para brindar un "servicio". Para minimizar el esfuerzo de implementar esta interfaz, J2EE provee una

Pgina 54 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
clase abstracta que brinda mtodos por defecto, y adapta la interfaz a un protocolo puntual. Un
Servlet HTTP es una clase que no slo implementa esa interfaz sino que hereda de la clase
javax.servlet.http.HttpServlet.
Todos los servlets deben figurar en el descriptor de despliegue del mdulo web. All se les asigna un
alias que relaciona una URL con la clase puntual del Servlet.
Tpicamente, un Servlet HTTP atiende las peticiones web a travs de varios mtodos. Ocurre que esta
clase divide el mtodo service() de Servlet en los mtodos doGet(), doPost(), doDelete(),
doOptions(), doPut() y doTrace(), de los cuales los ms utilizados son los dos primeros. El mtodo
doGet() que recibe las peticiones que usan formato GET, y el mtodo doPost, que atiende las
peticiones en formato POST. Generalmente se desea que el comportamiento del Servlet sea el mismo
en ambos casos, por lo que suele ponerse, en el cuerpo de uno de estos mtodos, una llamada al otro.
En un Servlet se pueden especificar las tareas necesarias durante su ciclo de vida (mtodos init() y
destroy()). No es que se diga cundo se instanciar, sino que al escribir el constructor, o el mtodo
destroy, se est diciendo qu se har cuando sea instanciado y cuando sea eliminado. Asimismo
pueden utilizarse "filtros" que se ubican como un entubamiento antes de la llamada a los mtodos de
servicio (doGet y doPost) del Servlet.
Desde un servlet podemos recuperar la informacin que se encuentra en el formulario inserto en el
objeto request. Esto se hace a travs del mtodo getParameter(String name).
Tambin podemos aadir informacin al objeto request, mediante el mtodo setAttribute(String
name, Object value). Asimismo, se puede aadir informacin al objeto session y al objeto
application (aunque este objeto recibe el nombre de ServletContext). Recordemos que el objeto
request es el que tiene el menor tiempo de vida: desde que el cliente hace una peticin hasta que
obtiene una respuesta a esa peticin. El objeto session "vive" desde que un cliente realiza su primera
peticin, hasta que la sesin expira; la sesin puede expirar por una sentencia explcita, o bien porque
transcurri el perodo de inactividad especificado en la aplicacin web. Finalmente, el objeto
ServletContext (application) existe desde que se inicia la aplicacin hasta que sta es finalizada (o
sea que el ciclo de vida es prcticamente concordante con el ciclo de vida del contenedor).
La forma de obtener estos objetos es:
// Obtencin del ServletContext (application)
ServletContext sc = this.getServletContext();
// o lo que es lo mismo
ServletContext sc2 = this.getServletConfig().getServletContext();
// Obtencin del objeto session (si no existe, devuelve null)
HttpSession ses = request.getSession(false);
// Obtencin del objeto session (si no existe, lo crea);
// idntico a utilizar getSession(true)
HttpSession ses2 = request.getSession();
En el otro sentido, si podemos aadir informacin a estos objetos con los mtodos setAttribute,
podemos consultar esta informacin con los mtodos Object getAttribute(String name), tanto
desde el Servlet como desde un JSP. Tambin se puede utilizar el mtodo removeAttribute(String
name) para quitar un atributo.
Existen varias formas de direccionar el trfico desde un Servlet hacia otro recurso web (Servlet o JSP).
La primera forma es obtener un objeto RequestDispatcher desde el objeto request.
RequestDispatcher rd = request.getRequestDispatcher("../std/fset.jsp");

Pgina 55 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Ntese que el objeto RequestDispatcher se relaciona con el recurso destino al momento de crearse.
Una vez que tenemos este objeto, llamamos al mtodo forward del mismo pasando como parmetros
los objetos request y response con los que estuvimos trabajando en el Servlet.
rd.forward(request, response);
Una alternativa a esta forma es obtener el objeto RequestDispatcher desde el objeto
ServletContext. En este caso, la URL con la que se relaciona el objeto slo podr ser una URL
absoluta (en el caso anterior puede ser absoluta o relativa).
RequestDispatcher rd =
this.getServletContext().getRequestDispatcher("/jsp/std/fset.jsp");
Finalmente, aparte de hacer un forward se puede hacer un redirect hacia el recurso de destino. En
este caso, lo que en realidad hacemos es devolver al cliente un cdigo especial en la respuesta,
indicando que el recurso no se encontraba en el servidor donde se estaba buscando, por lo que se lo
redireccionar hacia otro servidor. Como se advierte, esta forma tiene un alto costo de performance,
puesto que la peticin volver al cliente, y de all de dirigir de nuevo al servidor (al mismo o a otro),
por lo que debera evitarse. De todas formas, la manera de hacerlo es:
response.sendRedirect("/jsp/std/fset.jsp");

JSPs
La tecnologa JSP es una especializacin de los Servlets. Estn pensados para escribir la respuesta
HTML que se devolver al cliente. Anteriormente a su introduccin, los Servlets se encargaban de las
dos tareas: ejecutar lgica, y escribir la respuesta. Algo que recuerda a CGI, pero que tiene como
problema que mezcla cdigo Java con HTML, reduciendo la legibilidad del archivo y volvindolo grande
y, en casos extremos, muy dificil de entender y mantener.
PrintWriter pw = response.getWriter();
pw.write("<html><head>");
Estas fueron las razones para que se creara un componente que se compila tal como en Servlet (slo
que se compila y ejecuta dinmicamente al recibir la primera peticin), pero que se ve como un
documento HTML. Otra ventaja de esto es que el rol de maquetador de pginas Web no necesita saber
Java.
Cada pgina es automticamente compilada a un Servlet por el motor de JSP la primera vez que esa
pgina es solicitada. Una vez que se compila, se ejecuta y el cdigo compilado queda a disposicin del
contenedor por si reciba nuevamente una peticin a esa pgina. El cdigo compilado se desechar
cuando el contenedor lo estime necesario.
Una pgina JSP es archivo de texto simple que consiste en contenido HTML o XML con elementos JSP.
El cdigo fuente de una pgina JSP incluye:

Directivas: Dan informacin global de la pgina, por ejemplo, importacin de clases, pgina
que majena los errores, bibliotecas de tags que se utilizarn, etc.
Scripts de JSP: Es el cdigo Java embebido en la pgina (se llaman Scriptlets).
Expresiones de JSP: Formatea las expresiones como cadenas para incluirlas en la pgina de
salida.
Cdigo HTML y Javascript: muestra textualmente el cdigo que se enviar en la respuesta.

Pgina 56 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Una directiva de JSP es una declaracin que proporciona la informacin del motor de JSP para la
pgina que la pide. Su sintaxis general es:
<%@ directiva {atributo ="valor"} %>
dnde la directiva debe tener un nmero de atributos. Por ejemplo:
<%@ page import="java.util.Vector, java.math.BigDecimal" %>
En realidad, lo que ocurre es que se estn seteando atributos (por ejemplo, el atributo import) de un
objeto (por ejemplo, el objeto page). Otras directivas aparte de page son "include", para incluir
archivos completos palabra por palabra, y "taglib", para incluir bibliotecas de etiquetas personalizadas.
Para la directiva "page", otros atributos aparte de import son "errorPage", que indica la URL de la
pgina que manejar las excepciones de JSP, y el atributo "isErrorPage", un booleano que indica si se
trata de una pgina de error o de una pgina comn.
Los Scriptlets son bloques de cdigo Java residentes entre los tags <% y %>.
Hay algunos objetos implcitos disponibles para los Scripts desde entorno del Servlet. Vamos a verlos
a continuacin:

request: Es la peticin del cliente. Es normalmente una subclase de la case


HttpServletRequest.
response: Es la pgina JSP de respuesta y es una subclase de HttpServletResponse.
pageContext: Los atributos de la pgina y los objetos implicitos necesitan ser accesibles a
travs de API, para permitir al motor de JSP compilar la pgina. Pero cada servidor tiene
implementaciones especficas de cada uno de esos atributos y objetos. Para solucionar este
problema, el motor de JSP utilizar una clase factory para devolver la implementacin de clase
PageContext del servidor. Esta clase PageContext es inicializada con los objetos response y
request y algunos atributos de la directiva de la pgina (erropage, session, buffer y
autoflush) y facilita los otros objetos implcitos para la pagina de peticin.
session: El objeto de sesin HTTP asociado a la peticin.
application: Es lo que devuelve el Servlet cuando se llama a
getServletConfig().getContext(), o bien a getServletContext().
out: El objeto que representa la salida de texto por pantalla. Es lo que se obtiene con el
mtodo response.getWriter();
config: El objeto ServletConfig de la pgina.
page: Es la forma que tiene la pgina para referirse a si misma. Se usa como alternativa al
objeto this
exception: Es una subclase libre de Throwable que es pasada a la pgina que majena los
errores.

Finalmente, las expresiones son una magnifica herramienta para insertar cdigo embebido dentro de
la pgina HTML. Cualquier cosa que este entre los tags <%= y %> ser evaluado, convertido a
cadena y posteriormente mostrado en pantalla. La conversin desde el tipo inicial a String es
manejada autmaticamente.
Cuando se trabaja con archivos JSP, es crucial entender cabalmente los ditintos tiempos en los que se
ejecutar la pgina. Primero existe el tiempo en que el motor compila la pgina. Para este tiempo es
imprescindible realizar todas las importaciones necesarias. Luego viene el tiempo de ejecucin de la
pgina, donde se ejecutarn todos los Scriptlets y se evaluarn las expresiones, formando as un nico
documento HTML de respuesta. Este documento debe contener toda la informacin necesaria para el
tercer tiempo de ejecucin. El ltimo tiempo de ejecucin es cuando la respuesta llega al cliente, y el
cliente interacta con ella a travs de JavaScript.

Pgina 57 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Desde una pgina JSP podemos dirigirnos a otro componente enviando el formulario que
generalmente se encuentra dentro de ella (haciendo un submit desde JavaScript), o bien modificando
la direccin del objeto location.href, aunque de esta ltima forma no dispondremos del formulario.
Para finalizar, cuando trabajo en esta capa recomiendo:

Utilizar slo un formulario por pgina. Son realmente pocas las veces en que necesitamos ms
de un formulario. Entonces, dejemos la complejidad y suciedad de los mltiples formularios
para los casos estrictamente necesarios.
Utilizar como nombre de formulario una palabra corta y representativa. Mi nombre favorito es
"fo".
Cerrar TODAS las etiquetas HTML, como si se tratase de XML (donde s es obligatorio cerrar
todos los tags). De esta forma nos ahorramos problemas con errores muy simples.
Hacer el submit de un formulario por JavaScript. Aparte de ser necesario la mayora de las
veces, el cdigo queda ms mantenible.
Utilizar el mtodo POST en vez del mtodo GET. De esta forma evitamos mostrar en la caja de
direccin del browser la informacin interna de la aplicacin.
Al igual que el segundo punto de esta lista, esta recomendacin es para aplicar no slo en
pginas JSP sino en todo el cdigo que realicemos: INDENTAR !.

Taglibs
Cuando programamos pginas JSP existen Scriptlets que se utilizan muy a menudo. Por ejemplo,
hacer un Scriptlet para un bucle for, o para un if, o una expresin JSP para recuperar un valor.
Es interesante la idea de utilizar tags o etiquetas para llevar a cabo estas funciones de lgica, porque
dejan ms limpio y legible el cdigo, y porque quitan del desarrollador de pginas JSP la
responsabilidad de saber Java. Pinsese en que es comn que a esta tarea de escritura del JSP la
realicen diseadores grficos. Entonces, el tiempo y costo que se ahorra una empresa por no necesitar
que los desarrolladores JSP conozcan Java es muy considerable.
Para ello, SUN provey las APIs necesarias para que todos pudiramos escribir las bibliotecas de tags
que considersemos necesarias en nuestro proyecto. Y adems, ofreci un conjunto de bilbiotecas
"estndar", el JSTL (JSP Standard Tag Library) que nos proporcionan las funcionalidades ms
comunes.
La JSTL se encuentra implementada por SUN y por el proyecto Jakarta de Apache.
Para utilizar una taglib es necesario utilizar la directiva taglib en el archivo JSP. Esta directiva
establece con un prefijo a utilizar en las llamadas a los tags de la biblioteca, y una URI donde se
encuentra definida. Adems, puede ser necesario incluir algunos .jar al proyecto, y/o archivos tld que
contienen el conjunto de tags definidos por el .jar. Tambin puede ser necesario declarar los taglibs
utilizados por la aplicacin en el archivo web.xml.
Por ejemplo, en el JSTL se encuentran definidas cuatro bibliotecas para manejo de XMLs, de SQL, de
formateo y de estructuras de control y repetitivas. Este ltimo conjunto se denomina "core". Para
disponer de l basta con incluir unos archivos denominados jstl.jar y otro llamado standard.jar. Luego,
se utiliza una directiva como:
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
y ya se pueden utilizar los tags:
<c:if test='${error != null}'>
<h1>Error de login</h1>
</c:if>

Pgina 58 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Adems, en este caso se est utilizando Expression Language (EL) dentro del atributo test para
acceder al atributo error (un atributo definido por el usuario) del objeto request sin necesidad de
utilizar un Scriptlet.

JNDI
El Java Naming & Directory Interface es el framework de Java que, similarmente a la funcin de JDBC,
proporciona una interfaz estndar para los servicios de nombres y de directorios existentes. Estos
servicios son muchos y muy variados, pero en general se caracterizan por publicar un nombre como
referencia a un recurso. Este recurso podra ser desde una simple variable hasta un archivo o una
impresora, pasando por una clase o ben una interfaz.
Los nombres JNDI se registran generalmente en la confiuracin del servidor, aunque podran aadirse
nombres JNDI desde el cdigo.
Desde la aplicacin, para buscar un nombre primero debemos partir de un contexto. Si ese contexto
es el del servidor actual, simplemente podemos crear un objeto InitialContext llamando al constructor
por defecto:
InitialContext ctx = new InitialContext();
Si no fuera as, debemos construir el objeto utilizando un objeto Properties (que contiene un HashMap
por debajo) con las propiedades del contexto que deseamos instanciar. Por ejemplo, para indicar la
clase factory del contexto, y la URL del proveedor (esto es, del servidor donde se buscarn los
nombres), se podra utilizar:
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
props.put(Context.PROVIDER_URL, "192.168.1.73:1099");
InitialContext ctx = new InitialContext(props);
Desde la aplicacin, buscar un nombre es sumamante simple. Basta con utilizar el mtodo lookup del
contexto. Este mtodo devuelve un Object, por lo que ser necesaro un casting hacia la clase
adecuada:
DataSource ds = (DataSource) ctx.lookup("jdbc/mysqlDS");

DataSources
Un DataSource es un objeto capaz de devolver conexiones a una base de datos puntual. Las
conexiones que devuelve son ms bien "lgicas", pues en realidad establecer slo UNA conexin real
con el servidor de datos, y sobre ella har un "pool" o lista de conexiones.
Un DataSource se configura en el servidor, sea a travs de una interfaz grfica, o bien directamente
modificando los archivos de configuracin del servidor puntual.
Aparte de la mejora de rendimiento, la idea era lograr que la configuracin de la base de datos a la
que debe comunicarse una aplicacin sea independiente de la aplicacin en s; de esta forma, se
puede cambiar de un motor a otro sin necesidad de tocar (y recompilar y re-desplegar) una sla lnea
de cdigo Java.

EJBs (2.0)

Pgina 59 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Un Enterprise Java Bean es un componente de servidor, generalmente encargado de la lgica de
negocio de una aplicacin. A partir de aqu, utilizar la palabra "bean" para referirme a los EJBs, que
nada tienen que ver con JavaBeans, unos componentes reutilizables, no de servidor, y pensados
principalmente para el uso de "reflection", la tcnica de deducir la estructura de un objeto en tiempo
de ejecucin. Los EJBs deben ser implementados en un proyecto EJB y ejecutarse en un contenedor
EJB apropiado.
Existen tres tipos bsicos de beans, los de sesin, los de entidad, y los manejados por mensajes. Los
dos primeros son sncronos, o sea que al realizarse una peticin (una llamada a un mtodo) el cliente
espera la respuesta para continuar con su cdigo. Los manejados por mensajes son asncronos, el
cliente enva un "mensaje" al bean y contina con su cdigo sin esperar la respuesta.
Los beans de entidad representan las clases de entidad del negocio. Podra parecer una redundancia
pero no lo es: el concepto de entidad es anterior a los beans, y excede los lineamientos de este curso.
Simplemente podemos decir que si necesitamos guardar la informacin de una clase en la base de
datos, entonces estamos tratando con una entidad. A esto de guardar la informacin de un objeto en
la base de datos se denomina "persistencia" del objeto. La persistencia puede estar a cargo del
contenedor (container managed persistance) o bien a cargo del mismo bean (bean managed
persistance).
Por otro lado, las clases pueden ser gestores. En este caso no contienen informacin que interese
directamente al negocio como las entidades, sino que estas clases tienen como fin cordinar el trabajo
de otras clases, sean estas de entidad o bien otros gestores. Estas clases se modelan a travs de los
Session Beans. Existen dos tipos de SB: los que guardan informacin de las peticiones que
antendieron en el pasado (son los beans "con estado", o stateful) y los que no ("sin estado", o
stateless).

Stateless
Session Beans
Stateful

BMP
EJB

Entity Beans
CMP

Message Driven Beans

Si bien la forma de trabajo vara segn estemos utilizando un tipo de bean u otro, para la
instanciacin de un bean segn la especificacin 2.0 se utilizan dos interfaces y una clase. Las
interfaces son la "inicial" o home, y la remota. Cuando se desea utilizar un bean, lo primero a hacer es
obtener una instancia de la interfaz Home utilizando JNDI. Esto de una "instancia de la interfaz" es la
forma simplificada de decir que en el proveedor se crea un objeto y al cliente se devuelve la interfaz,
similar al trabajo que se realiza en JDBC o con WebServices. La obtencin de la referencia no puede

Pgina 60 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
recurrir a un casting explcito como se vi con DataSources, sino que es necesario utilizar el mtodo
esttico narrow de la clase PortableRemoteObject:
InitialContext ctx = new InitialContext();
Object ref = ctx.lookup("ejb/com/ini/ValidateHome");
ValidateHome valHome = (ValidateHome) PortableRemoteObject.narrow(ref,
ValidateHome.class);
Una vez que tenemos la interfaz Home, llamando al mtodo create() obtenemos una interfaz
Remote, ligada a una instancia de la clase del bean en el servidor. Desde esta interfaz Remote
podemos llamar a los mtodos de negocio del bean.
Validate val = valHome.create();
Integer empId = val.validarLogin(usr, pwd);
El ciclo comentado se muestra en la siguiente figura:

En general, los nombres de las clases y las interfaces siguen una nomenclatura fija. Si el bean se
llamase Empleado, la interfaz remota se llamar simplemente Empleado, la clase de implementacin
del bean se llamar EmpleadoBean, y la interfaz Home se llamar EmpleadoHome.
Cuando el bean se encuentra en el mismo contenedor desde donde se lo quiere utilizar, se utilizan
interfaces locales (EmpleadoLocalHome sera la interfaz Home y EmpleadoLocal sera la interfaz
remota).
Recordemos que los EJBs fueron pensados para ser consumidos no slo desde programas Java, sino
desde cualquier programa que pueda adaptarse al estndar CORBA.
Otra particularidad de los beans es que estn pensados para ser consumidos remotamente. Para ello,
el cliente debe contar con las interfaces, que se empaquetan en un archivo JAR de cliente EJB.
La seguridad para el acceso al bean suele quedar a cargo del contenedor, especificndosela en el
descriptor de despliegue (ejb-jar.xml, en este caso).

WebServices

Pgina 61 de 62

walter.a.montesano@accenture.com
Manual de Java + J2EE
Un WebService es un mtodo que puede ser invocado remotamente. El concepto viene de la
arquitectura SOA (Service Oriented Architecture), implementada por Microsoft a travs de estos
"WebServices". O sea que esta tecnologa no tiene relacin con J2EE, salvo porque puede ser
implementada en aplicaciones que siguen el modelo J2EE.
Un WebService puede estar implementado en una variedad de lenguajes, as como el cliente que lo
consume, siempre que en esta comunicacin se utilice el protocolo SOAP (Simple Object Access
Protocol).
Si bien con RMI primero, y con los EJB despus, ya era posible llamar a mtodos de objetos remotos
en Java, con los WebServices se maximiza la simplicidad y la independencia entre las aplicaciones
proveedor y cliente, puesto que la interfaz que debe conocer el cliente es slo un archivo XML,
puntualmente el WSDL, o WebService Description Language (ntese que el acrnimo no designaba en
principio al archivo, sino al lenguaje; pero en el uso corriente, con ese nombre se designa al archivo
de descripcin puntual de un WebService). En cambio, cuando se trabaja con EJBs, el cliente debe
conocer dos interfaces Java, an cuando no es obligatorio que el cliente en s est programado en este
lenguaje.
El WebService puede concebirse para ser consumido desde una aplicacin local, desde una intranet, o
bien desde la internet. Al ser utilizado remotamente, desde la intranet o desde internet, se debe
utilizar un "proxy" que rutear las llamadas que se dirigen a la interfaz del cliente hacia el objeto
remoto. Adems, cuando se lo desea publicar hacia la internet, es necesario utilizar algn servicio de
directorio como bien puede ser UDDI.

Pgina 62 de 62

You might also like