HolaMundo.java
Ing. Pablo Augusto Sznajdleder
Simple
Orientado a Objetos
Distribuido
Interpretado
Robusto
Seguro
Multiplataforma
Portable
Multithreaded
Java es un lenguaje de programacin orientado a objetos cuya sintaxis es muy similar a la del lenguaje de
programacin C++. Es un lenguaje fuertemente tipado, sensitivo a maysculas y minsculas, etc.
La similitud con el lenguaje C hace que los programadores con conocimientos previos de C se sientan
familiarizados con el cdigo fuente. Pero Java es un lenguaje mucho mas simple que C y C++.
Para comenzar, en Java no existe la aritmtica de punteros de C. No es que en Java no existan los
punteros. Justamente todo lo contrario: todos los objetos en Java son punteros (o referencias) y como
todos los objetos son punteros no es necesario definirlos explcitamente (por ejemplo con * como en C)
logrando as un cdigo muy claro, prolijo y transparente (y sin los temidos asteriscos de C y C++).
Java proporciona las herramientas necesarias para programar orientado a objetos: encapsulamiento de
datos, sobrecarga de funciones, herencia y polimorfismo. Tiene un extenso rbol de clases que abarcan
desde manejo de cadenas de caracteres (String) hasta procesamiento distribuido, serializacin de objetos,
acceso a bases de datos, etc. Todo en Java son clases y objetos (excepto las variables de tipos de datos
primarios short, int, long, byte, char, float, double, boolean y las palabras reservadas).
La multiplataforma se logra mediante la Maquina Virtual Java o JVM. La maquina virtual es quien,
partiendo de las complejidades propias de cada plataforma (set de instrucciones, registros, etc.) lleva a
todas las plataformas a una complejidad homognea sobre la cual los programas Java son ejecutados.
Es decir para poder ejecutar una aplicacin Java es necesario disponer de una JVM. Los sistemas
operativos modernos (Solaris, Linux, entre otros) traen incorporada la JVM como parte de lo que se llama
el Java Runtime Enviroment o JRE. Para los sistemas operativos que no lo tengan preinstalado, el JRE
puede bajarse gratuitamente desde la direccin http://java.sun.com e instalarse como cualquier aplicacin.
Otra caracterstica de Java (quiz la mas popular en los comienzos) es la posibilidad de desarrollar
Applets. Un applet es un programa Java que es ejecutado dentro de un navegador y distribuido on-
demand a travs de un web-server.
La posibilidad de tener programas completos, distribuidos on-demand y ejecutndose absolutamente en
la maquina del cliente potencializ el modelo webtop, ampliamente ventajoso respecto del modelo
1
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
descktop ya que en tal modelo se minimizan los costos de mantenimiento de soft, de hard, de datos y de
instalacin, as como los costos de licenciamiento y de distribucin.
En el caso de los applets la JVM es implementada por el navegador. As, el cliente no necesita
preocuparse por nada. Simplemente teniendo el navegador en su computadora ya esta habilitado para
acceder a paginas web que contengan applets.
Java implementa una serie de chequeos tanto en tiempo de compilacin como en tiempo de ejecucin que
facilitan al programador la tarea de depurar errores de lgica y le evitan cometer bugs, que por su
naturaleza seran muy difciles de depurar. A continuacin veremos un cuadro comparativo entre C y Java
en el que se exponen algunas situaciones habituales y muy desagradables para los programadores C.
Otro ejemplo muy buen ejemplo es el recolector de residuos o Garbage Collector. el GC es un proceso
que dispara la JVM y se ocupa de revisar el estado de asignacin de memoria buscando bloques de
memoria desreferenciados. Cuando encuentra un bloque que no esta siendo referenciado por ningn
puntero simplemente lo libera.
En otros lenguajes el programador debe estar muy atento para ver en que situaciones puede estar dejando
memoria desreferenciada y entonces liberarla explcitamente. Por ejemplo en C usando la funcin free().
2
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
LA PLATAFORMA DE INTERNET
Las aplicaciones para Internet, por su naturaleza requieren una plataforma pensada en niveles o capas
como se ilustra en el siguiente grfico.
En la capa cliente el browser juega el papel principal. En la mayora de los casos la interface grfica o
front-end de las aplicaciones esta basada en HTML o Applets y es bajada o distribuida en el
momento en que el usuario enva el requerimiento. Las aplicaciones que requieren interfaces mas
complejas pueden desarrollarse e instalarse en el cliente independientemente del browser.
La capa del servidor de presentacin consiste en un web-server que maneja requerimientos HTTP y
genera dinmicamente cdigo de presentacin para ser visualizado en el cliente.
Los servidores de aplicacin son quienes albergan lgica de negocios, la que idealmente puede ser
reutilizada en diferentes clientes y aplicaciones. La lgica de negocios debe ser accesible desde clientes y
servidores para facilitar la integracin de aplicaciones. La capa se aplicacin tambin se encargar de
generar informes y anlisis de tipo gerencial.
Finalmente la capa de datos contiene bases de datos escalables, capaces de almacenar, manipular,
retribuir y analizar los requerimientos de las aplicaciones de Internet. Esta capa tambin puede contener
fuentes de datos externas como middle-wears, etc.
3
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
El modelo multicapa descripto anteriormente se ajusta a la especificacin Java2, Enterprise Edition
Application Programming Model propuesto por Sun Microsystems en http://java.sun.com/j2ee/apm/
Las interfaces HTML son generadas dinmicamente por los web-servers usando Java Server Pages (JSP)
y Servlets. Puede incrementarse la funcionalidad y la productividad ensamblando libreras reusables de
JavaBeans. Los clientes 100% puro Java pueden desarrollarse como applets, como aplicaciones o como
applets que puedan correr a su vez como aplicaciones independientes del browser.
Los application servers habilitados con Java contienen componentes de negocios distribuidos y reusables
tanto CORBA como EJB. Los componentes de negocios tpicamente encapsulan la datos y servicios e
interactuan con la persistencia de los mismos accediendo a las bases de datos va JDBC.
4
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
2. Hola Mundo !!!
Toda aplicacin Java es una clase. Cada clase
HolaMundo.java debe almacenarse en un archivo con extensin
.java y con el mismo nombre que la clase.
As, la clase HolaMundo debe estar en el
public class HolaMundo
archivo HolaMundo.java
{
public static void main(String args[])
{
System.out.println( HOLA MUNDO !!! );
}
}
Como podemos ver (al igual que en C) todo bloque de cdigo se delimita con { ... }. Al finalizar cada
instruccin se debe finalizar la lnea con ;
Estos trminos los analizaremos
cuando expliquemos los conceptos
public Alcance del mtodo main(). de programacin orientada a
objetos.
static Mtodo esttico o mtodo de la clase.
void Tipo de dato del valor de retorno.
String args[] Argumentos en lnea de comandos.
COMPILACION Y CORRIDA
Se deben respetar en todo momento las
maysculas y minsculas. Tanto en el
c:\> javac HolaMundo.java cdigo fuente como en el nombre del
c:\> java HolaMundo archivo, en la compilacin y en la
HOLA MUNDO !!! ejecucin.
c:\>
5
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
JEcho.java Programa que recibe
argumentos en lnea de
public class JEcho comandos y los escribe en la
{ standar output.
public static void main(String args[])
{
for( int i=0; i<args.length; i++ )
{
System.out.println( args[i] );
}
}
}
COMPILACION Y CORRIDA
6
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
A continuacin vemos la lista de palabras reservadas del lenguaje.
PALABRAS RESERVADAS
abstract do implements private throw
boolean double import protected throws
break else instanceof public transient
byte extends int return true
case false interface short try
catch final long static void
char finally native super while
class float new switch
continue for null synchronized
default if package this
La siguiente tabla indica la cantidad de bits que son asignados a las variables de cada tipo de datos. Dado
que los programas Java corren sobre la JVM estas longitudes son vlidas para todas las plataformas en las
que se implemente la maquina virtual. En C (por ejemplo) las longitudes dependen de la plataforma.
7
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Estructuras de Repeticin Como podemos ver, las estructuras de
control tanto de repeticin como de
decisin son las idnticas a las de C.
while( condicin ) do
{ {
: :
} } while( condicin )
8
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
3. PROGRAMACION ORIENTADA A OBJETOS
Para entender los conceptos de la teora de objetos plantearemos una serie de ejemplos que iremos
desarrollando progresivamente.
ENCAPSULAMIENTO
Supongamos que tenemos que desarrollar una aplicacin para manejar nmeros complejos. Si pensamos
en programacin estructurada estaremos pensando en una estructura (struct de C o record de Pascal)
como la siguiente:
struct Complejo
{
int r; // componente real del numero complejo.
int i; // componente imaginario.
}
main( )
{
Complejo c;
Lo anterior implica un doble problema para el programador de la funcin main(). Por un lado el problema
propio de manipular los nmeros complejos (su verdadero problema) pero por otro lado el programador
tiene que conocer de antemano como estn definidas las variables de la estructura complejo que
representan las componentes real e imaginaria. En este caso las variables son r e i respectivamente.
Si en lugar de pensar la estructura complejo como struct Complejo la pensamos como class Complejo:
class Complejo
{
private int r; // componente real del numero complejo.
private int i; // componente imaginario.
}
las asignaciones c.r = 10 y c.i = 3 son incorrectas ya que las clases (por definicin) proveen
encapsulamiento para sus datos. Decimos entonces que los datos de la clase Complejo estn
encapsulados y la nica forma de accederlos es a travs de funciones que la misma clase provea.
9
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Entonces podemos decir que una clase es una estructura que combina datos con las funciones necesarias
para manipularlos. Llamamos Objeto a toda variable cuyo tipo de datos es una clase.
Resumiendo
Clase: estructura que combina datos con las funciones (o mtodos) necesarias para
accederlos.
Objeto: variable cuyo tipo de datos es una clase.
La idea es que el usuario (en este caso el programador que utiliza la clase Complejo) no tenga que
preocuparse por la complejidad propia de la clase.
Las asignaciones anteriores implican conocer de antemano que los datos se almacenan en variables
llamadas r e i. Esto nos hace entrar en complejidades ajenas a nuestra incumbencia.
En programacin orientada a objetos la misma clase tiene que proveer los mtodos necesarios para
acceder a los datos; mtodos para asignar valor a los datos, para consultar el valor de los datos y para
efectuar operaciones entre los datos.
class Complejo
{
private int r; Atributos del nmero complejo. Como veremos
private int i; mas adelante tambin se dice que son variables de
instancia.
public void setReal(int re)
{
r = re; Una buena prctica es definir para
} cada dato (o atributo)
un mtodo set y un mtodo get.
public void setImag( int im)
{
i = im;
}
10
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
main( )
{
Complejo c = new Complejo( );
c.setReal(10); // asigno 10 al componente real
c.setImag(3); // asigno 3 al componente imaginario
c.imprimir( ); // imprimo por pantalla el numero complejo c
System.out.println( La componente real es=+c.getReal());
}
Un objeto en Java en realidad es un puntero a un rea de memoria, por lo tanto es necesario asignarle una
direccin vlida. Para esto utilizamos el operador new.
El operador new recibe como argumento el constructor de la clase. El constructor de la clase es un mtodo
ms pero que es llamado automticamente al momento de asignar memoria al objeto.
Toda clase tiene al menos un constructor. Si no lo programamos explcitamente, igual existe un
constructor nulo por default.
El constructor, para ser reconocido como tal debe llamarse exactamente igual que la clase y no debe
tener valor de retorno (ni siquiera void).
pero como la clase Complejo tiene los mtodos setReal() y setImag() que se ocupan de realizar las
asignaciones, el constructor quedara mejor programado de la siguiente forma:
main( )
{
Complejo c =new Complejo (10,3);
c.imprimir( );
}
11
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
SOBRECARGA
Supongamos que nuestra clase Complejo quedo terminada y esta en produccin. Muchas aplicaciones la
utilizan y no se registr ningn tipo de problema. Pero ahora surge la necesidad de que las aplicaciones
puedan construir nmeros complejos expresndolos como suma de sus componentes. Por ejemplo el
nmero complejo (10,3) = 10+3i. Cualquiera de las dos expresiones representan al mismo nmero
complejo. La sobrecarga permite agregar funcionalidad a la clase sin correr el riesgo de alterar lo que ya
esta funcionando sin problemas.
Sobrecargar un mtodo simplemente es escribirlo dos o mas veces (en la misma clase) pero con diferentes
prototipos y por supuesto diferentes cuerpos.
class Complejo
{
int r; El constructor esta sobrecargado: el primero
int i; recibe dos enteros. El segundo recibe un
String.
public Complejo( int re, int im )
{
setReal( re );
setImag( im );
}
:
:
}
En el ejemplo adems de sobrecargar el constructor se asume que los mtodos setReal() y setImag() estn
sobrecargados tambin. En el primer constructor se los invoca con un argumento de tipo int, mientras que
en el segundo con uno de tipo String.
Notemos que el argumento s es de tipo String, y String es una clase. Por lo tanto decimos que s es un
objeto String y como tal tiene los mtodos necesarios para asignar, retribuir, y manipular su valor.
12
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public void setImag(String s)
{
int posmas = s.indexOf(+);
String aux = s.substring( posmas+1, s.length()-1 );
int valimag = Integer.toString( aux );
setImag( valimag );
}
Complejo.java
public Complejo(String c)
{
setReal(c);
setImaginario(c);
}
13
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public void setImaginario(String s)
{
int posmas=s.indexOf('+');
String si=s.substring(posmas+1,s.length()-1);
int vi=Integer.parseInt(si);
setImaginario(vi);
}
c1.imprimir();
c2.imprimir();
}
}
API java.lang.String
POLIMORFISMO
Vamos a explicar ahora el concepto mas importante del paradigma de objetos. Polimorfismo es el ncleo
de la teora de objetos y su comprensin resulta fundamental para encarar cualquier desarrollo.
Si este concepto no se logra comprender en su totalidad, todo lo dems (herencia, sobreescritura, clases
abstractas, etc. ) resultar anecdticos y carente de potencial.
14
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Supongamos que tenemos que realizar una aplicacin para el rea de RRHH de una empresa. Luego del
un anlisis decidimos disear la clase Empleado.
main( )
{
Empleado e =new Empleado( 1010, Pedro Gomez );
e.imprimir( );
}
Siguiendo con el anlisis nos encontramos con un gerente. Es obvio que un gerente tiene los mismos
atributos que un empleado (legajo, nombre) y otros propios que lo caracterizan como tal. Por ejemplo un
Sector a Cargo.
Podemos decir entonces que un Gerente es un Empleado y por lo tanto tiene las mismas caractersticas.
La clase Gerente debe heredar las propiedades de la clase Empleado.
main( )
{
Empleado e = new Empleado( 1010, Pedro Gomez);
Gerente g = new Gerente ( 1515, Pablo Perez, 20 );
e.imprimir( );
g.imprimir( );
}
15
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
En la funcin main() el objeto g (o la instancia g de la clase Gerente) utiliza el mtodo imprimir() que
hereda de la clase base Empleado. El problema es que el mtodo imprimir() que Gerente hereda no se
adapta por completo a las caractersticas de la clase. Digamos que le queda chico, ya que solo imprime
los datos propios de un empleado (legajo y nombre) y no tiene en cuenta los datos del gerente como ser
sac (sector a cargo).
La solucin es redefinir el mtodo imprimir() en la clase Gerente para que se adapte a los requerimientos
de la clase. En este caso decimos que sobreescribimos el mtodo imprimir().
Notemos que la primera lnea del mtodo imprimir() de la clase Gerente llama a super.imprimir()
(mtodo de la clase base). Es decir que en imprimir() de Gerente solo tenemos que hacer el trabajo propio
para la impresin de los datos del gerente. La responsabilidad de la impresin los datos heredados queda
por cuenta del mtodo imprimir() del padre (Empleado).
Seamos ahora un poco mas exigentes con la clase Gerente. Un gerente seguramente tendr gente a su
cargo. Podra ser muy til que el mtodo imprimir() de Gerente no solo imprima los datos del gerente,
sino tambin los datos de toda la gente a su cargo.
Para esto vamos a modificar la clase Gerente agregndole una estructura capaz de almacenar un conjunto
de empleados y un mtodo que permita agregar empleados a dicha estructura.
16
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
import java.util.Vector;
Ahora en la funcin main() podemos hacer que un gerente est a cargo de un empleado.
main( )
{
Empleado e = new Empleado(1010, Mariano Chimiel);
Gerente g = new Gerente(2020, Gerardo Gebel);
g.ponerACargo( e );
}
El siguiente paso es modificar el mtodo imprimir() de la clase Gerente imprima la ficha de cada uno de
los empleados que el gerente tiene a su cargo.
Notemos que es necesario castear a Empleado el resultado del mtodo elementAt() del vector lga. Este
mtodo retorna una instancia (cuyo tipo es Object, no Empleado). Debemos notar tambin que el mtodo
addElement() en realidad espera un tipo de datos Object, no un Empleado. Sin embargo nosotros le
pasamos una instancia de Empleado y esto no es un error. En Java todas las clases heredan (o son
subclases) de la clase (base) Object.
En nuestro ejemplo: Gerente extends Empleado (Gerente es Empleado) y Empleado extends Object
(Empleado es Object) por lo tanto Gerente es Object.
Se dice entonces que Empleado matchea contra Object y puede utilizarse como argumento del mtodo.
Cuando invocamos el mtodo elementAt() y pretendemos que el vector nos devuelva los datos que le
ingresamos, resulta que dicho mtodo tiene como valor de retorno un Object y la clase Object no tiene
17
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
ningn mtodo llamado imprimir(). Casteando a Empleado podemos decir que recuperamos el objeto de
tipo Empleado que originalmente ingresamos en el vector mediante la funcin addElement().
Es muy importante comprender que gerente es un empleado y que un empleado es un object, por lo que
un gerente es un object.
main( )
{
Empleado e1,e2,e3;
Gerente g1,g2;
g1.ponerACargo( e1 );
g1.ponerACargo( e2 );
g2.ponerACargo( e3 );
g1.ponerACargo( g2 ); // recordemos que g2 es tambin un empleado
A simple vista parece haber un problema. En la vuelta i=2 el elemento almacenado en el vector es un
objeto Gerente, pero para imprimir estamos casteando a Empleado. La pregunta es la siguiente: Que
imprimir se le aplica a g2: el de Gerente o el de Empleado? La respuesta es por polimorfismo se
ejecuta el imprimir de Gerente.
Podemos decir entonces que cada objeto sabe a que clase pertenece y por lo tanto sabe que mtodos tiene
disponibles (antes de tener que recurrir a las que hereda de su padre). La necesidad de castear se debe a
que por tratarse de un lenguaje fuertemente tipado los tipos de datos deben ser bien conocidos de
antemano por el compilador y debemos asegurarle a este que el dato que estamos sacando del vector
(como Object), en realidad tiene el mtodo imprimir() que le estamos aplicando. Es decir: nos hacemos
responsables ante el compilador de que el mtodo imprimir() existe en la instancia g2 (y en todos los
objetos que iremos sacando del vector).
Es importante destacar que si la clase Object tuviera un mtodo imprimir() el casteo no sera necesario.
Podramos aplicarle libremente el este mtodo a los objetos almacenados en el vector teniendo la
seguridad de que el imprimir() llamado siempre ser el adecuado.
La versin completa de las clases Empleado, Gerente y una clase TestEmpleados estn a continuacin.
18
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Empleado.java
public class Empleado
{
private int leg;
private String nom;
public Empleado(int l,String n)
{
leg=l;
nom=n;
}
public void imprimir()
{
System.out.println("Legajo="+leg+" Nombre="+nom);
}
}
Gerente.java
import java.util.Vector;
public class Gerente extends Empleado {
private int sac;
private Vector lga;
public Gerente(int l,String n,int s) {
super(l,n);
sac=s;
lga=new Vector();
}
public void ponerACargo(Empleado e) {
lga.addElement(e);
}
public void imprimir()
{
super.imprimir();
System.out.println(Sector=+sac);
for(int i=0; i<lga.size(); i++ )
{
( (Empleado)lga.elementAt(i) ).imprimir();
}
}
}
19
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
API java.util.Vector
AppEmpleados.java
e1=new Empleado(10,"Juan");
e2=new Empleado(11,"Pedro");
e3=new Empleado(12,"Jose");
g1=new Gerente(50,"Analia",1);
g2=new Gerente(51,"Martin",2);
g1.ponerACargo( e1 );
g1.ponerACargo( e2 );
g2.ponerACargo( e3 );
g1.ponerACargo( g2 );
g1.imprimir();
}
}
COMPILACION Y CORRIDA
c:\> javac *.java
c:\> java AppEmpleados
Legajo=50 Nombre=Analia
Sector=1
Legajo=10 Nombre=Juan
Legajo=11 Nombre=Pedro
Legajo=51 Nombre=Martin
Sector=2
Legajo=12 Nombre=Jose
c:\>
20
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
CONVENCIONES DE NOMENCLATURA
Si bien no es obligatorio, por cuestiones de convencin es aconsejable respetar una serie de reglas de
nomenclatura para las clases, los mtodos, variables, y constantes. Todas las clases de la librera Java
fueron escritas respetando esta convencin de forma que conocindola ya no tendremos que preocuparnos
por recordar (por ejemplo) cuales caracteres del nombre de una clase son mayscula y cuales minscula.
NOMENCLATURA
Clases
Siempre comienzan con Mayscula. Si el nombre se compone de varias palabras
entonces cada inicial debe ser en Mayscula.
Mtodos
Siempre comienzan con minscula. Si el nombre se compone de varias palabras
entonces cada inicial debe ser en Mayscula.
Constantes
Completamente en Mayscula. Si el nombre se compone de varias palabras
entonces cada palabra se separa de la anterior por medio del carcter _
Variables
Nunca deben comenzar en Mayscula. Puede utilizarse la misma nomenclatura
definida para los mtodos.
21
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Como comentamos en la introduccin, en Java todos los objetos son punteros o referencias a bloques de
memoria previamente alocada por medio del operador new.
Definamos la clase X (lase equis grande) para utilizarla en una secuencia de ejemplo.
Instancias Desreferenciadas GC
class X
{ Variables de
private int a; Instancia
private int b;
a b
x2=new X(4,8); x2
4 8
En el siguiente paso haremos la asignacin x2=new X(...) haciendo apuntar a x2 a una nueva instancia
dejando la anterior sin referenciar (en otras palabras: ningn puntero la esta apuntando).
a b Instancia
x2=new X(5,9); x2 Desreferenciada
4 8
a b
5 9
Ahora, como la instancia (4,8) esta desreferenciada ser eliminada automticamente por el Garbage
Collector.
Antes de probar lo anterior explicaremos brevemente otro concepto de la teora de objetos: las variables
y los mtodos de clase.
22
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Modificador Variable Mtodo
static Variable de clase Mtodo de clase
El modificador static aplicado a una variable la convierte en variable de la clase. Esto quiere decir que es
una variable cuyo valor ser compartido por todas las instancias. As, si una instancia modifica su valor
automticamente las dems instancias vern alterado el valor de la variable. Simplemente porque la
comparten.
El mismo modificador aplicado a mtodos los convierte en mtodos de la clase. Un mtodo de clase
puede aplicarse directamente sobre la clase, sin tener que generar una instancia para utilizarlo. Ejemplos
de mtodos de clase son Integer.parseInt(...), Math.pow(...), Thread.sleep(...), etc.
El siguiente es un ejemplo interesante. La clase TestGC tiene la variable de clase contador que al
momento de definirla se inicializa en 0. Luego, cada vez que la clase es intanciada (en el constructor) se
incrementa su valor y se imprime. Recordemos que por ser una variable de clase las instancias sucesivas
vern el valor incrementado.
En la clase TestGC se sobreescribe el mtodo public void finalize(). Este mtodo esta definido en la
clase base Object y es invocado automticamente por el Garbage Collector antes de destruir una instancia
desreferenciada.
En nuestro ejemplo, sobreescribimos el mtodo finalize() para detectar el momento en que la instancia
ser eliminada y entonces decrementamos el valor de contador.
El mtodo main() simplemente dispara instancias continuamente y no las mantiene referenciadas.
En otros lenguajes este programa terminara con un error de tipo out of memory. Sin embargo, como
Java cuenta con el Garbage Collector la memoria que esta sin referenciar es liberada automticamente y
as el programa puede correr sin generar ningn tipo de error.
TestGC.java
public TestGC() {
contador++;
System.out.println(contador);
}
El mtodo finalize() es invocado
automticamente por el Garbage
public void finalize() { Colector antes de eliminar una instancia
contador--; desreferenciada.
}
23
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
CORRIDA
CLASES ABSTRACTAS
Vamos a explicar ahora el concepto de clases abstractas, otro de los conceptos de la teora de objetos que
se relaciona fuertemente con el polimorfismo.
Pensemos en una clase para manejar figuras geomtricas: si bien para toda figura geomtrica se puede
calcular su rea, resulta que es imposible calcular el rea de una figura geomtrica sin saber previamente
de que figura estamos hablando. No es lo mismo calcular el rea para un crculo que para un rectngulo.
As y todo, podemos definir la clase FigGeom con el mtodo rea() como mtodo abstracto. Entonces
las subclases de FigGeom (Circulo, Tringulo, Rectngulo, etc.) debern sobreescribir adecuadamente el
mtodo rea().
Como la clase FigGeom tiene al menos un mtodo abstracto debe ser declarada como clase abstracta. Una
clase abstracta no puede ser instanciada. Veamos el cdigo de la clase FigGeom.
Como podemos ver, en el mtodo printArea() se llama al mtodo rea(). Esto puede resultar confuso por
ser rea() un mtodo abstracto. Pero como las clases abstractas no pueden ser instanciadas, resulta que el
mtodo printArea() solo ser aplicado a instancias de las subclases de FigGeom, las que ya
sobreescribieron el mtodo rea(). As, por polimorfismo la referencia al mtodo rea() ser sobre la
subclase y nunca sobre la clase FigGeom.
Veamos como las clase Circulo y Rectangulo resuelven el mtodo rea() de la forma mas conveniente.
24
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Circulo.java
public Circulo(double r)
{
radio=r;
}
Rectangulo.java
public class Rectangulo extends FigGeom {
private double base,altura;
Ahora, podemos pensar en una clase TestAbstract que haga uso de las clases Circulo y Rectangulo.
25
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
TestAbstract.java
public class TestAbstract {
public static void main(String args[]){
Circulo c=new Circulo(3);
Rectangulo r=new Rectangulo(5,2); Recordemos que printArea() llama a
rea(), pero como lo estamos
c.printArea(); invocando desde instancias de Circulo
r.printArea(); y Rectangulo , por polimorfismo se
invocara al mtodo area() de Circulo y
Rectangulo respectivamente.
FigGeom fg[]=new FigGeom[2]; Podemos decir entonces que cada
fg[0]=c; figura sabe como resolver su propio
fg[1]=r; area.
double prom=areaPromedio(fg);
System.out.println( prom );
}
API java.lang.Math
26
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Modificador Msma clase Sub-clase Externa Msmo paquete
public X X X X
protected X X
private X
default X X
INTERFACES
En la figura vemos una instancia de la clase Monitor que es vista por instancias de las clases Usuario,
EmpleadoDelDeposito y MedicoDeOjos. Cada una de estas instancias esta interesada en aspectos
diferentes de la clase instancia de monitor. Por ejemplo: al usuario solo le interesa poder setearle el brillo,
el contraste y poder encenderlo y apagarlo. Al empleado del depsito le interesan aspectos relacionados
con las dimensiones para poder ver en que estantera lo va a depositar, si lo va a poder levantar o si va a
necesitar una gra, etc. Al medico de ojos le interesan aspectos relacionados con la salud. Por ejemplo
que redaccin emite.
getDimension()
setBrillo() getPeso()
setConstraste() getVolumen()
setEncendido() Instancia de
la clase
Monitor
esPantallaPlana()
getRadiacion() Instancia de
EmpleadoDelDeposito
Instancia de
Usuario
Instancia de
MedicoDeOjos
27
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Veamos el cdigo de las interfaces propuestas en el ejemplo.
Ahora vemos el cdigo de la clase Monitor que implementa las interfaces. Notemos que la clase monitor
extiende a la clase AparatosConCRT por lo que las interfaces no limitan la herencia.
:
}
28
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public class Usuario
{
private AspectosFuncionales monitor;
public Usuario(AspectosFuncionales m)
{
monitor=m;
}
:
}
public Usuario(AspectosMedicinales m)
{
monitor=m;
}
:
}
public Usuario(AspectosDimensionales m)
{
monitor=m;
}
:
}
Como vemos, la instancia de
Monitor matchea contra
Y ahora veamos una funcion main que utilize todo lo anterior. AspectosFuncionales,
AspectosMedicinales y contra
AspectosDimensionales. Obviamente
public static void main(String args[]) tambin contra Monitor y contra
{ AparatosConCRT.
Monitor monitor=new Monitor();
Pensando en un proyecto con varios programadores y analistas. El uso de interfaces es muy interesante.
Los analistas pueden definir (y escribir) las interfaces que deben implementar las clases que desarrollaran
los programadores. De esta forma se aseguran que los programadores respetaran 100% los nombres de
mtodos definidos ya que si se equivocan tan solo en una mayscula o minscula no podrn compilar.
Las intefaces permiten un nivel de abstraccin fundamental. Supongamos que nos encargan un mtodo
para ordenar elementos. No habra ningn problema si los elementos fueran enteros, caracteres o String.
Ya que estos tienen un orden natural. Pero que pasara si los elementos fueran monitores ???.
Los monitores no tienen un orden natural y el criterio de precedencia no es nico.
29
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
La solucin a este problema es definir una interface Ordenable con un mtodo:
public boolean precedeA(Object o);
As, la clase Monitor puede implementar esta interface y especificar el criterio de precedencia para los
monitores.
Ahora el mtodo que ordena puede abstraerse y solo recibir instancias de Ordenable. Lo incluiremos en
una clase Util que englobara mtodos (estticos) utilitarios.
30
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Ahora en una funcin main podemos trabajar de la siguiente forma.
main()
{
Monitor monitores[]=new Monitor[10];
Planteando la solucin de esta forma logramos abstraernos de las caractersticas propias de los elementos
a ordenar. Nos alcanza simplemente con que cada elemento pueda decidir sobre si precede o no a otro
elemento de su misma especie.
Con el mismo criterio podemos implementar la interface Ordenable en la clase Empleado y estaremos en
condiciones de ordenar empleados usando el mismo mtodo ordenar() de la clase Util.
main()
{
Empleado empleados[]=new Empleado[10];
As, desarrollamos un mtodo totalmente reusable que nos permite ordenar objetos sin tener en cuenta a
que clase pertenecen. Solo deben ser instancias vlidas de Ordenable.
31
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
4. MANEJO DE EXCEPCIONES
El manejo de excepciones es una forma de manejo de error orientado a objetos. La idea es mantener un
cdigo limpio y prudente. Esto es: intentar una secuencia de operaciones y en caso de que alguna falle
entonces emprender las acciones correctivas necesarias.
Cualquier ejemplo de la vida real puede ilustrar el uso de las excepciones. Supongamos que en este
momento me da sed. Muy bien, las acciones que debo realizar para saciar mi sed son las siguientes:
caminaraHastaLaPuerta()
abrirLaPuerta()
caminarHastaLaCocina()
servirmeAguaEnUnVaso()
Es obvio que si mientras camino hasta la puerta me tropiezo y me rompo una pierna entonces no voy a
intentar abrir la puerta ni mucho menos seguir caminando hasta la cocina. Voy a tratar de tomar el
telfono (como pueda) para llamar al mdico. Pero si logro llegar con xito hasta la puerta entonces la
intentare abrir. Claro que puede estar trabada entonces ni intento caminar hasta la cocina porque ser
intil. Mi problema ser lograr abrir la puerta.
As, generalmente se da que para una sucesin de mtodos, el mtodo i+1 debe realizarse si y solo s el
mtodo i finalizo con xito. A su vez, el mtodo i debi haberse ejecutado si y solo si el mtodo i-1
resulto exitoso. Veamos un cdigo que ilustre este ejemplo.
Si un mtodo falla al ser
Manejo de Excepciones invocado entonces dispara
una excepcin predefinida y
: el control del programa pasa
try al catch correspondiente.
{
caminarHastaLaPuerta();
abrirLaPuerta();
caminarHastaLaMaquinaDeAgua();
servirAgua();
}
catch(TropezonException ex)
{
System.out.println(Me tropeze !!!);
}
catch(PuertaNoAbreException ex)
{
System.out.println(Ohh nooo !!!);
}
catch(NoHayAguaException ex)
{
System.out.println(No hay agua en el bidn...);
}
catch(Exception ex)
{
System.out.println(Error inesperado);
ex.printStackTrace();
}
:
32
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
API java.lang.Exception
public Exception()
public Exception(String mssg)
public void printStackTrace()
public String getMessage()
Para tratar con excepciones tenemos dos posibilidades: una es capturar la excepcin que dispara el
mtodo utilizando la sentencia catch. Pero muchas veces no es nuestra responsabilidad emprender las
acciones correctivas. En ese caso simplemente debemos propagar el error (prototipando el mtodo con
la palabra throws) para que se haga cargo nuestro llamador. A su vez, si el puede tratar la excepcin lo
har mediante un bloque try-catch pero si no puede tratarlo entonces propagar el error y as
sucesivamente.
El siguiente ejemplo es una clase con tres mtodos: f1(), f2() y f3(). Si el mtodo f1() falla entonces
disparara una excepcin del tipo F1Exception. Anlogamente si f2() o f3() fallan dispararan F2Exception
y F3Exception respectivamente.
Los mtodos reciben un boolean error con el que indicaremos si queremos que el mtodo falle o no. Si
error=true entonces el mtodo disparara la excepcin que le corresponde. Si no finalizara con xito.
Un mtodo que eventualmente pueda disparar una excepcin debe prototiparse con la palabra throws.
Esto forzara al llamador del mtodo a encerrarlo en un bloque try-catch o bien a propagarlo el error.
SimpleException.java
public class SimpleException {
public void f1(boolean error) throws F1Exception
{
System.out.println("Comienza f1()"); Como error=true entonces
disparo una instancia de
F1Exception.
if( error )
{
throw new F1Exception();
}
System.out.println("Termina f1() ok!");
}
public void f2(boolean error) throws F2Exception
{
System.out.println("Comienza f2()");
if( error )
{
throw new F2Exception();
}
if( error ) {
throw new F3Exception();
}
errorF1= Boolean.valueOf(args[0]).booleanValue();
errorF2= Boolean.valueOf(args[1]).booleanValue();
errorF3= Boolean.valueOf(args[2]).booleanValue();
Las excepciones F1Exception, F2Exception y F3Exception son clases que debemos programar. Para
programar una excepcin simplemente debemos programar una clase que herede de la clase base
Exception.
34
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
F1Exception.java
De igual forma se
public class F1Exception extends Exception programan las clases
F2Exception y
{ F3Exception
}
COMPILACION Y CORRIDA
El ejemplo anterior esta pensado para que el lector pueda probar todos los casos haciendo variar los
parmetros de entrada (por lnea de comandos). Luego es recomendable que se pruebe programando la
funcin main() de la siguiente forma:
main() propaga el error,
as no es necesario un
public static void main(String args[]) throws Exception bloque try-catch
{
boolean errorF1,errorF2,errorF3;
errorF1= Boolean.valueOf(args[0]).booleanValue();
errorF2= Boolean.valueOf(args[1]).booleanValue();
errorF3= Boolean.valueOf(args[2]).booleanValue();
Para finalizar, analizaremos un fragmento de un programa servidor (el programa completo se estudiar en
el capitulo de networking).
35
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public class SimpleServer
{
public static void main(String args[]) throws Exception
{
int port=5432;
int queve=10;
Socket s1;
ObjectOutputStream oos; Si falla la creacin del
ServerSocket se propaga el error y
el programa finaliza aqu. Esto esta
while( true ) bien, ya que si fallo el
{ ServerSocket el servidor no tiene
try nada que hacer.
{
s1=ss.accept();
Este bloque try-catch
no sera necesario a
oos=new ObjectOutputStream(
los efectos de s1.getOutputStream() );
compilacin, pero si oos.writeObject( Hola NET Mundo);
a los efectos de la oos.close();
aplicacin. s1.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
En este ejemplo tenemos la creacin del ServerSocket que eventualmente podra disparar un IOException.
Es claro que si falla el new ServerSocket( ... ) el servidor no tiene sentido ya que no podr atender ningn
requerimiento. En este caso la excepcin ser propagada a travs de la sentencia throws colocada en el
prototipo del mtodo main().
Si el serverSocket se construyo con xito entonces se ingresa al while(true) dentro del cual se van a
recibir las conexiones de los clientes a travs del mtodo ss.accept(). Este mtodo eventualmente podra
fallar tambin y disparar un IOException. Si bien, al propagar el error en el mtodo main estamos
cubriendo esta posibilidad y a los efectos de compilacin estamos cubiertos, a los efectos de la aplicacin
no seria prudente aceptar esta situacin porque si ss.accept() falla en realidad esta fallando la conexin de
un cliente, pero es posible que el prximo cliente no falle. Por eso, al encerrar todo el cdigo en un bloque
try-catch tratamos puntualmente la excepcin originada con el cliente problemtico y no permitimos que
la excepcin sea propagada finalizando prematuramente el mtodo main().
36
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
5. APPLET
Los applets son aplicaciones Java embebidas en paginas html. As, el interprete del applet es el browser.
Por cuestiones de seguridad para el cliente (usuario del applet) los applets tienen una serie de
restricciones que les impiden ser destructivos. Por ejemplo no pueden tener ningn tipo de acceso al disco
rgido del cliente, no pueden tener mtodos nativos, no pueden convertirse en servidores y no pueden
conectarse a otro host que no sea el host desde el que provienen.
Object paint(Graphics g)
Component update(Graphics g)
Container repaint()
Window
Frame
Panel init()
Applet start()
Button stop()
Label destroy()
Choice getParameter(String param)
: getDocumentBase()
Veamos el HolaMundoApplet.
HolaMundoApplet.java
import java.awt.*;
import java.applet.*;
HolaMundoApplet.html
<applet code=HolaMundoApplet.class height=200 width=200>
</applet>
COMPILACION Y CORRIDA
37
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Area del applet (color griz). El Graphics g
es un puntero a este rea. A travs de l
tenemos acceso grfico para, por ejemplo,
escribir un texto que diga Hola Mundo !!!
El siguiente ejemplo muestra como manejar imgenes. Las imgenes bajan desde la web utilizando el
mtodo getImage(). Este mtodo recibe un objeto URL que apunte al host desde donde fue enviado el
documento html. Ese URL se obtiene utilizando el mtodo getDocumentBase(). El segundo argumento de
getImage() es el imagename. Este es un String que indica el nombre de la imagen. Puede ser .gif o .jpg.
Inclusive un gif animado. El imagename puede incluir tambin el path. Por ejemplo imagenes/pp.gif.
Notemos que el path es relativo. Nunca debemos utilizar un path absoluto como /imagenes/pp.gif.
Tambin vemos que el imagename esta parametrizado. El paso de parmetros al applet se hace a travs de
la pgina html. Los parmetros son por nombre, no por posicin. El mtodo getParameter() recibe como
argumento el nombre del parmetro y devuelve el valor del mismo como String. El tag para pasar
parmetros lo podemos ver en ImagenApplet.html (a continuacin).
ImagenApplet.java
import java.awt.*;
import java.applet.*;
public class ImagenApplet extends Applet{
El nombre de la imagen
private Image img=null; esta parametrizado en la
pgina html.
public void init() {
try {
String imgname=getParameter(IMAGE_NAME);
img=getImage(getDocumentBase(),imgname);
MediaTracker mt=new MediaTracker(this);
mt.addImage(img,0);
mt.waitForAll();
} catch(Exception ex) { El MediaTracker
permite monitorear si las
ex.printStackTrace(); imgenes que bajamos
} con getImage() estn
} listas para ser utilizadas.
public void paint(Graphics g) {
g.drawImage(img,0,0,this);
}
}
38
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
ImagenApplet.html
<applet code=ImagenApplet.class height=300 width=300>
<param name=IMAGE_NAME value=imagenes/T1.gif>
</applet> Tag para pasarle parmetros al
applet. Se pueden poner tantas
lneas como esta como sea
API java.awt.Graphics necesario.
API java.awt.MediaTracker
public void addImage(Image img, int id)
public boolean checkID(int id)
public boolean checkAll()
public boolean waitForID(int id)
public boolean waitForAll()
CAPTURA DE EVENTOS
Los componentes generan eventos de diferentes tipos. Por ejemplo cuando el usuario presiona un botn
(ya sea con el mouse o con la barra espaciadora) espera que ocurra alguna accin. Cuando se hace doble-
click en un tem de una lista se espera que ocurra una accin. Pero si se selecciona un tem de una lista
con un solo click no se espera que ocurra nada. Cuando se escribe en un campo de texto no espera
ninguna accin, pero cuando se presiona ENTER en el campo de texto luego de haber escrito el contenido
se espera una accin.
Es decir: existen eventos de action, de key, de tem, de mouse, de window, etc.
El componente genera eventos e informa a quienes estn interesados en ser notificados ante la ocurrencia
de los mismos. Las clases aptas para escuchar eventos se llaman listeners.
Siguiendo con el ejemplo ImagenApplet, vamos ver como detectar los eventos de mouse.
39
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
import java.awt.*;
import java.awt.event.*; Con este mtodo le pasamos al
import java.applet.*; applet una instancia de
EscuchaMouse para que cuando
public class ImagenApplet extends Applet genere algn evento de mouse la
{ notifique.
La clase EscuchaMouse es una
private Image img=null; inner class que implementa la
interface MouseListener.
public void init() {
try {
addMouseListener( new EscuchaMouse() );
:
Una inner class no es mas que una clase
} catch(Exception ex) { dentro de otra. La gran ventaja de estas clases
ex.printStackTrace(); es que pueden ver los mtodos y las variables
de la clase que las contiene como si fueran
} propios. Pero el hecho de que sean inner class
} no tiene absolutamente nada que ver con la
: herencia. En este caso, EscuchaMouse hereda
de Object e implementa MouseListener
ADAPTERS
Los adapters son clases que implementan las interfaces listener y sobreescriben todos sus mtodos
dejndolos vacos. As le evitan al programador la tediosa tarea de sobreescribir mtodos que no va a
utilizar. Para cada listener existe un adapter.
40
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Interface definida en
ADAPTERS Ejemplo MouseAdapter java.awt.event.
Tiene cinco mtodos abstractos.
public interface MouseListener
{
public void mouseEntered(MouseEvent e);
Clase definida en java.awt.event.
public void mouseExited(MouseEvent e); Implementa MouseListener y
public void mousePressed(MouseEvent e); sobreescribe todos sus mtodos
public void mouseReleased(MouseEvent e); dejndolos vacos.
public void mouseClicked(MouseEvent e); Quien extienda a MouseAdapter
} matchea contra MouseListener y
no hereda ningn mtodo abstracto.
Ventajas Desventajas
XListener Si tipeamos mal el nombre de Debemos tipear todos los mtodos. Aunque
algn mtodo se genera un error en solo nos interese uno.
tiempo de compilacin.
41
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
6. INTERFACE GRAFICA
Para armar una interface grfica (GUI) en Java tenemos tres elementos:
El esquema es simple:
Un container contiene componentes. Los componentes son distribuidos (o acomodados) dentro del
container en funcin del layout que el container tenga especificado.
LAYOUT MANAGER
Layout Size 1 Size 2
Flow
Arriba y centrado
Border
Se divide el
container en
cinco regiones.
Se puede colocar
un solo
componente en
cada regin
Grid (3,3)
Una grilla de n
filas y m
columnas. Se
coloca un
componente
por celda.
42
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Como podemos ver, a medida que la ventana es redimensionada los componentes se acomodan
proporcionalmente respetando la distribucin que le fue asignada.
El siguiente rbol muestra la estructura de las clases para armar GUIs en Java.
Ventana.java
import java.awt.*;
API java.awt.Frame
43
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
TestGUI.java
import java.awt.*;
import java.awt.event.*;
public class TestGUI extends Frame
Recordemos que
{ FlowLayout distribuye
public TestGUI() los componentes arriba
{ y centrados
super(Test);
setLayout( new FlowLayout() );
setSize(380,260);
Esta instancia de EscuchaCerrar ser
setVisible(true); notificada cuando la ventana genere
} algn evento de ventana.
API - java.awt.*
Component Mtodos
Label public Label(String texto)
Button public Button(String texto)
Checkbox public Checkbox(String texto)
public setState(boolean b)
public boolean getState()
TextField public TextField(int ancho)
public String getText()
public void setText(String texto)
44
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
TextArea public TextArea(int alto, int ancho)
public String getText()
public void setText(String texto)
public void append(String texto)
Choice public Choice()
public void addItem(String item)
public String getSelectedItem()
public int getSelectedIndex()
List public List()
public void add(String item)
public void setMultipleMode(boolean b)
public int getItemCount()
public String getSelectedItem()
public int getSelectedIndex()
public String[] getSelectedItems()
public int[] getSelectedIndexes()
Veamos ahora un ejemplo en el que se combinen los diferentes layout managers presentados para generar
una interface grfica til.
NORTH
CENTER
SOUTH
La funcionalidad de esta pantalla es la siguiente: cuando se presiona el botn Ok el texto que est tipeado
en el textfield superior pasara a la lista que esta en la parte central. Cuando se presiona el botn Limpiar
se borraran todos los tems de la lista.
45
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
ConsultaGUI.java
import java.awt.*;
import java.awt.event.*;
Panel psouth;
psouth=new Panel( new FlowLayout(FlowLayout.LEFT) );
Button bLimpiar=new Button(Limpiar);
SOUTH bLimpiar.addActionListener( new EscuchaLimpiar() );
psouth.add( bLimpiar );
Cuando se presione el
add( psouth, BorderLayout.SOUTH ); botn Limpiar se
notificara a la instancia
addWindowListener( new EscuchaCerrar() ); de EscuchaLimpiar
setSize(380,260);
setVisible(true);
}
46
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public static void main(String args[])
{
new ConsultaGUI();
}
47
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
7. MULTITHREAD
La multiprogramacin permite descomponer una aplicacin en diferentes tareas que se ejecutan
concurrentemente y cooperan entre s para lograr el objetivo de la aplicacin.
Un buen ejemplo de una aplicacin multithread es un Servidor. A su vez, para entender como trabaja un
servidor vamos a poner un ejemplo de la vida real.
Un servidor es un almacenero. El almacenero esta de 9 a 20 hs. detrs del mostrador esperando que
llegue algn cliente a comprarle algo. Cuando llega un cliente el almacenero comienza a atenderlo.
Si llega otro cliente y el almacenero todava esta atendiendo al cliente anterior, el nuevo cliente formara
una fila. Cuando llegue otro cliente se pondr al final de la fila y as sucesivamente.
Supongamos que el primer cliente no esta muy decidido sobre lo que va a comprar. No puede decidir
entre llevar kilo de galletitas o una bandeja de masitas. Mientras tanto, el segundo cliente (esta en la
cola) que solo quiere un atado de cigarrillos y tiene el importe justo tiene que esperar que el primer cliente
se decida. Esta situacin no es optima, ya que el segundo cliente que demorara unos 30 segundos tiene
que estar 15 minutos en la cola porque el almacenero esta atendiendo al indeciso que llego antes que el.
Como el almacenero ve que tiene muchos cliente y el negocio marcha muy bien decide contratar 5
empleados: Juan, Pablo, Jos, Ral y Felipe.
Cuando llega un cliente el almacenero le pide a alguno los empleados que lo atienda. Cuando llega otro
cliente el almacenero le indica a otro empleado que lo atienda y as sucesivamente.
Como podemos ver, cada empleado trabaja independientemente y entre todos cumplen el objetivo del
almacenero que es atender y despachar bien.
Sin embargo aparecen situaciones nuevas que no existan cuando el almacenero trabajaba solo. Por
ejemplo no pueden dos empleados utilizar la balanza al mismo tiempo. Porque si los dos ponen el
producto que quieren pesar en la balanza al mismo tiempo el resultado no seria correcto.
En el ejemplo el almacenero es la aplicacin (el servidor) y los empleados son tareas (thread). La balanza
es un recurso crtico cuyo acceso debe ser sincronizado.
public HolaMundoMT(String n)
En el constructor recibe un String
{ name.
name=n;
}
48
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
El mtodo run() es a los Thread lo que
public void run() el mtodo main() es a las aplicaciones.
{ Escribir un thread es (entre otras
try cosas) sobreescribir este mtodo.
{
int delay=(int)(Math.random()*3000);
sleep(delay); El thread dormir un
tiempo aleatorio entre 0
System.out.println( y 3 segundos.
"Hola Mundo MT !!! "+name);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
public static void main(String args[])
{
HolaMundoMT t1=new HolaMundoMT("Pedro");
HolaMundoMT t2=new HolaMundoMT("Pablo");
HolaMundoMT t3=new HolaMundoMT("Juan");
start() llama al mtodo run(). No debe
t1.start();
llamarse a mano al mtodo run().
t2.start();
t3.start();
}
}
COMPILACION Y CORRIDA
Como podemos ver, en cada corrida del
c:\> javac HolaMundoMT.java programa el resultado es distinto porque
depende del tiempo que duerma cada
c:\> java HolaMundoMT thread. Cada thread duerme un tiempo
HOLA MUNDO MT !!! Pablo aleatorio y como son ejecutados
HOLA MUNDO MT !!! Juan concurrentemente no se puede predecir nada
HOLA MUNDO MT !!! Pedro sobre cual ser la salida del programa. En
cada corrida la salida puede variar.
Esto prueba que los thread corren
c:\> java HolaMundoMT concurrentemente porque si su ejecucin
HOLA MUNDO MT !!! Juan fuese secuencial entonces la salida del
HOLA MUNDO MT !!! Pedro programa siempre sera Pedro, Pablo, Juan.
HOLA MUNDO MT !!! Pablo
Pensemos ahora en una animacin. Una animacin es una sucesin continua de imagenes. O sea un
while(true){ ... } . Si en una interface grfica (sea un Frame o un Applet) ponemos un while( true ) lo
estaremos colgando. La ventana no se repintara, los botones quedaran apretados, etc. Sin embargo, para
desarrollar nuestra animacin necesitamos el while( true ).
La solucin es tener un thread que se ocupe del while( true ). Al ser independiente, no interferir con el
control de la aplicacin y el resultado ser el esperado.
49
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
La animacin esta planteada de la siguiente manera. Existen dos clases: una clase pasiva y una clase
activa.
Decimos que la clase Animacion es pasiva porque se deja animar. Tiene un mtodo mostrarSiguiente()
que muestra la siguiente imagen. Es decir: se deja aplicar el mtodo mostrarSiguiente().
La clase Animador es la clase activa porque aplicara el mtodo mostrarSiguiente() a la clase Animacion.
Animador ser un thread en cuyo mtodo run() tendr un ciclo while( true ).
mt.waitForAll();
int ancho=imagenes[0].getWidth(this);
int alto=imagenes[0].getHeight(this);
setSize(ancho,alto);
}
public void setMovimiento(boolean animar)
{
if( animar )
Para comenzar la animacin
{ hay que aplicarle el mtodo
(thread=new Animador()).start(); setMovimiento(true).
} Entonces construimos y
else comenzamos (start) el thread.
{ Si aplicamos el mtodo
setMovimiento(false)
thread.stop(); entonces se mata al thread
} con el mtodo stop().
}
50
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public void paint(Graphics g)
{
g.drawImage(imgenes[index],0,0,this);
}
Hasta aqu hemos desarrollado el componente Animacin. Ahora desarrollaremos una clase que utilize
este componente y genere una ventana como la que se muestra a continuacin.
51
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
AnimacionTest.java
import java.awt.event.*;
import java.awt.*;
setSize(300,300);
setVisible(true);
}
public static void main(String args[]) throws Exception
{
new AnimacionTest();
}
class EscuchaButtons implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
animacion.setMovimiento( e.getSource().equals(bcom) );
}
}
}
52
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
THREAD LIFE CICLE Diagrama de los cinco estados
El diagrama precedente describe el ciclo de vida de un thread. El thread pasa por 5 estados a lo largo de
su evolucin. Cuando lo creamos con el operador new se dice esta en el estado new thread. Cuando le
aplicamos el mtodo start() decimos que el thread esta en cola de listos o ready to run. A partir de
entonces el thread pasara entre ese estado y el estado running. En running el thread esta haciendo uso
del procesador (CPU). La planificacin de CPU esta a cargo de un proceso de mas bajo nivel llamado
Scheduler. Cuando el thread intente una operacin den entrada/salida pasara a una cola de bloqueados
Blocked y de esta volver a la cola de listos. Cuando finalize el mtodo run() el thread pasara a su
ltimo estado: dead.
SINCRONIZACION DE THREADS
La solucin a este problema est a continuacin. Son cuatro clases: Buffer, Producer, Consumer y
ProdConsTest.
53
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Buffer.java
public class Buffer {
private char buff[];
private int size=6, index=0;
private boolean lleno=false, vacio=true;
public Buffer() {
buff=new char[size];
}
public synchronized void poner(char c) throws Exception
{
while( lleno ) {
wait(); Mientras el buffer este lleno el
} productor que llamo a este mtodo
no podr poner el carcter. Entonces
buff[index++]=c; ser bloqueado hasta que sea
vacio=false; notificado mediante el mtodo
notify().
if( index>=size ) {
lleno=true; Es probable que algn consumidor este
} bloqueado esperando que este productor
produzca algn carcter. Con este
mtodo lo notificamos para
notify(); desbloquearlo.
return;
}
char c=buff[--index];
lleno=false;
if( index == 0 ) {
vacio=true;
}
notify();
return c;
}
}
54
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Producer.java
public class Producer extends Thread {
private Buffer buffer;
private String alphabet=ABCDEFGHIJKLMNOPQRSTUVWXYZ;
Consumer.java
public class Consumer extends Thread{
private Buffer buffer;
public Consumer(Buffer s) {
buffer = s;
} Recibe un puntero al buffer.
Obviamente debe ser el mismo
buffer que se le paso al productor.
public void run() {
try {
char c;
for (int i = 0; i < 20; i++) {
c = buffer.sacar();
System.out.println(Saque = + c);
sleep((int)(Math.random() * 3000));
}
} catch (Exception ex) { ex.printStackTrace(); }
}
}
55
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
ProdConsTest.java
p.start();
c.start();
}
}
56
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
8. ENTRADA/SALIDA
Veremos a continuacin algunas clases del paquete java.io.
HolaMundoIO.java
import java.io.*;
public class HolaMundoIO
{
public static void main(String args[]) throws Exception
{
File f=new File(pp.txt); La clase File permite acceder al header
de un archivo. Provee mtodos tales
if( !f.exists() ) como canRead(), canWrite(), length(),
{ exists(), etc.
_grabarArchivo(f);
}
else
{
_leerArchivo(f);
}
}
57
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
API java.lang.String
public String(byte buffer[])
public byte[] getBytes()
API java.io.File
public File(String filename)
public boolean exists()
public long length()
public boolean canRead()
public boolean canWrite()
public boolean isFile()
public boolean isDirectory()
El siguiente rbol ilustra la jerarqua de algunas de las clases de input que pertenecen al paquete java.io.
Anlogamente existe un rbol similar para las clases de output.
JEditor.java
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class JEditor extends Frame
{
private TextArea ta;
private String filename;
public JEditor(String filename) throws Exception {
super(JEditor +filename);
this.filename=filename;
add( ta=new TextArea(), BorderLayout.CENTER );
_leer( filename );
addWindowListener( new EscuchaCerrar() );
}
58
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
private void _leer(String filename) throws Exception
{
File f=new File(filename);
FileInputStream fis=new FileInputStream( f );
byte buffer[]=new byte[ (int) f.length() ];
fis.read( buffer );
fis.close();
59
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
La clase FileDialog genera una caja de dilogo para seleccionar archivos y/o directorios.
API java.awt.FileDialog
public static final int SAVE
public static final int LOAD
public FileDialog(Frame owner, String titlebar, int mode)
public String getFile()
public String getDirectory()
public void setFile(String filename)
public void setDirectory(String dirname)
60
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
9. NETWORKING
ARQUITECTURA CLIENTE SERVIDOR
Hablamos de cliente-servidor cuando existe un proceso que requiere un determinado servicio y acude a
otro proceso para que se lo brinde.
Cuando navegamos por Internet, utilizamos el navegador. El navegador es un Cliente del servicio de
pginas web. Cuando tipeamos la direccin de la pgina a la que queremos acceder le estamos indicando
al navegador (cliente) la direccin del Servidor que le proveer la pgina que necesitamos.
Un muy buen ejemplo de como funciona esta arquitectura es el almacenero que presentamos en el
capitulo de Multithread.
El almacenero (server) abre su almacn a las 9 de la maana y se queda detraes del mostrador esperando
la llegada de los clientes. Los clientes entran al negocio cuando necesitan alguno de los productos
(servicios) que el almacn ofrece. Notemos que el almacenero no sabe en que momento llegan los
clientes.
Cuando llega un cliente el almacenero lo comienza a atender. Se establece un dialogo (protocolo) entre el
cliente y el almacenero.
Puede ser que cuando el cliente llega al almacn el almacenero esta atendiendo a otro cliente. El cliente
forma una fila (cola) y espera a que el almacenero despache al cliente que llego primero. Puede ser que el
almacenero se tome un tiempo excesivo para despachar al cliente (porque el cliente le pide demasiadas
cosas). Entonces el cliente que esta en la cola da media vuelta y se retira (timeout).
Por supuesto que seria mejor si el almacenero tuviera empleados (threads), entonces cada empleado se
ocupara de despachar a cada cliente.
SOCKET y PORT
Un Socket es un punto de intercomunicacin entre dos procesos (por ejemplo cliente y servidor). Los
procesos pueden estar en el mismo host (computadora) o no.
En un host pueden correr diferentes procesos brindando diferentes servicios. Por ejemplo servicio de
HTTP, de Telnet, de FTP, de SMTP, etc. Cada uno de estos procesos tiene una direccin que lo identifica
unvocamente respecto de los otros. Esta direccin se llama PORT.
Generalmente el servicio de HTTP se brinda en el port 80, el de Telnet en el 23, FTP en el 21 y SMTP en
el 25. Decimos entonces que un PORT es una direccin relativa. Identifica al proceso pero no identifica
al host en el que corre dicho proceso.
En una red TCP/IP como Internet cada host tiene una identificacin nica llamada nmero IP.
Un SOCKET es un nmero IP + un PORT. Por lo tanto es una direccin absoluta ya que identifica
unvocamente un proceso en toda la red.
61
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
SERVER CLIENTE
ServerSocket
accept()
Socket Socket
InputStream OutputStream
OutputStream InputStream
close close
SimpleClient.java
import java.net.*;
import java.io.*;
public class SimpleClient
{
public static void main(String args[]) throws Exception
{
Socket s1=new Socket(127.0.0.1, 5432);
ObjectInputStream ois;
ois=new ObjectInputStream(s1.getInputStream());
String s=(String)ois.readObject();
El cliente abre un
ois.close(); InputStream. El server
s1.close(); abrir un OutputStream
System.out.println( s );
}
}
API java.net.Socket
public Socket(String hostname, int port)
public InputStream getInputStream()
public OutputStream getOutputStream()
public InetAddress getInetAddress()
public void setSoTimeout(int millis)
public String getInetAddress().getHostAddress()
public String getInetAddress().getHostName()
62
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
API java.io.ObjectInputStream
public ObjectInputStream(InputStream is)
public Object readObject()
API java.io.ObjectOutputStream
public ObjectOutputStream(OutputStream os)
public void writeObject(Object obj)
SimpleServer.java
import java.net.*;
import java.io.*;
63
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Vamos a modificar el cliente y el servidor para que el dialogo sea ida y vuelta.
Modificacin en el Cliente
Socket s1=new Socket(127.0.0.1,5432);
ois=new ObjectInputStream(s1.getInputStream());
oos=new ObjectOutputStream(s1.getOutputStream());
Primero abre el InputStream y
String s=(String)ois.readObject(); luego el OutputStream.
System.out.println( s ); El server lo har al revs
oos.close();
ois.close();
s1.close();
Modificacin en el Server
Socket s1=ss.accept();
ois.close();
oos.close();
s1.close();
System.out.println( s );
Como vemos, el cliente y el servidor deben estar perfectamente sincronizados. Si el cliente abre un
InputStream entonces el servidor debe abrir un OutputStream y si luego el cliente abre un OutputStream
el servidor debe abrir un InputStream.
Para cerrar los streams se deben tener en cuanta la misma consideracin. Si el cliente cierra el
InputStream entonces el server debe cerrar el OutputStream y biseversa.
SERVIDOR MULTITHREAD
64
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
SimpleServerMT.java
import java.net.*; El server ahora ser un Thread
import java.io.*;
public SimpleServerMT(Socket s)
{
s1=s;
}
public static void main(String args[]) throws Exception
{
int port=5432;
int queve=10;
65
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public void run()
{
try
{
oos=new ObjectOutputStream( s1.getOutputStream() );
ois=new ObjectInputStream( s1.getInputStream() );
oos.writeObject(Hola NET MT Mundo !!!);
String s=(String)ois.readObject();
ois.close();
oos.close();
s1.close();
System.out.println(s);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
Para probar que efectivamente el servidor atiende concurrentemente los requerimientos de los diferentes
cliente se van conectando le haremos una pequea modificacin al cliente para que espere un tiempo
entre la lectura del Hola Mundo y la escritura del Gracias Server.
Primero dispararemos un cliente que demore 20 segundos y luego dispararemos un cliente que demore 3
segundos. Si el segundo cliente es despachado antes que el primero habremos probado que el servidor los
atendi concurrentemente, y mientras una instancia del server esta ocupada con el primer cliente que
demora 20 segundos, la otra se ocupo de despachar al segundo cliente que solo se tomo 3 segundos.
Modificacin en el Cliente
Socket s1=new Socket(127.0.0.1,5432);
ois=new ObjectInputStream(s1.getInputStream());
oos=new ObjectOutputStream(s1.getOutputStream());
// LEE
String s=(String)ois.readObject();
System.out.println( s );
// DUERME
Thread.sleep( Integer.parseInt(args[0]) );
// ESCRIBE
oos.writeObject(GRACIAS SERVER !);
oos.close();
ois.close();
s1.close();
66
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
COMPILACION Y CORRIDA
Este es un buen momento para desarrollar una aplicacin que combine todos los temas analizados. La
aplicacin Chat utiliza interface grfica, multithread y networking en un esquema cliente-servidor.
Esta aplicacin podemos desarrollarla fcilmente copiando y pegando cdigo de las clases
SimpleClient y SimpleServer desarrolladas anteriormente.
Cuando se presiona [ENTER] sobre el TextField (actionPerformed()) se debe enviar un mensaje al host
indicado en el Choice y con el texto que contenga el TextField. Esto simplemente implica crear un
Socket, crear un ObjectOutputStream, aplicarle writeObject() con el texto del TextField, cerrar el
ObjectOutputStream y cerrar el Socket.
Para implementar el server que reciba los mensajes debemos tener en cuanta que ya no tenemos el mtodo
main() a nuestra disposicin porque esta aplicacin. En esta aplicacin integra el cliente y el servidor por
lo tanto dicho mtodo solamente debe dedicarse a crear una instancia de la ventana.
Como el server debe estar continuamente recibiendo mensajes (while(true)) debe ser un Thread.
Veamos la solucin.
67
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
JChat.java Otra manera de manejar Threads.
Una instancia de Runnable
import java.awt.*; puede utilizarse para crear un
import java.awt.event.*; Thread.
import java.io.*; El mtodo run() esta definido en
import java.net.*; esta interface.
public class JChat extends Frame implements Runnable
{
private TextField tf;
private List lst;
private Choice ch;
public JChat(String hosts[])
{
super("JChat");
Panel pnorth=new Panel(new BorderLayout());
pnorth.add( new Label("Mensaje"), BorderLayout.WEST );
pnorth.add( tf=new TextField(), BorderLayout.CENTER );
tf.addActionListener( new EscuchaSend() );
ch=new Choice(); En lnea de comandos se
for( int i=0; i<hosts.length; i++ ) reciben todos los hostname
{ que participan en el chat.
ch.addItem(hosts[i]);
}
pnorth.add( ch, BorderLayout.EAST );
Disparo un Thread cuyo
add( pnorth, BorderLayout.NORTH ); mtodo run() ser en que se
add( lst=new List(), BorderLayout.CENTER ); define a continuacin. En
dicho mtodo se
( new Thread(this) ).start();
implementa el servidor de
addWindowListener( new EscuchaCerrar() ); recepcin de mensajes.
setSize(470,280);
setVisible(true);
}
new JChat(hosts);
}
68
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Este mtodo viene de la interface
public void run()
Runnable.
{
try
{
ServerSocket ss=new ServerSocket( 5432,10 );
Socket s1;
ObjectInputStream ois; Notemos la similitud con
String mssg; el SimpleServer.
String hostfrom;
while( true )
{
s1=ss.accept();
ois=new ObjectInputStream( s1.getInputStream() );
69
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
class EscuchaCerrar extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
setVisible(false);
dispose();
System.exit(0);
}
}
}
La versin anterior no puede utilizarse como applet para chatear en Internet. El problema principal que
presenta es que establece conexiones directas entre diferentes hosts. Recordemos que una de las
restricciones que se le imponen a los applets es la imposibilidad de conectarse a otro host que no sea el
host desde donde llego. Adems, la versin anterior utiliza un ServerSocket, caracterstica tambin
restringida a los applets.
En el apndice analizaremos una segunda versin valida para correr en Internet.
PROCESAMIENTO DISTRIBUIDO
RMI permite distribuir objetos Java entre los diferentes host de la red.
CORBA provee un entorno heterogneo en el cual pueden convivir objetos programados en diferentes
lenguajes de programacin como ser Java, C, C++, Cobol, etc.
Con RMI un programa cliente puede invocar mtodos de un objeto ubicado en un server remoto. Esto le
brinda al programador la posibilidad de distribuir el procesamiento permitiendo que cada tarea se ejecute
en el host mas conveniente.
En un esquema RMI intervienen tres partes: el cliente, el servidor y la interface de mtodos que el
servidor publicara y que podrn ser invocados por el cliente.
70
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
InterfaceRMI.java
import java.rmi.*;
public interface InterfaceRMI extends Remote
{
public String getDato() throws RemoteException;
}
SimpleServerRMI.java
import java.rmi.server.*;
import java.rmi.*;
SimpleClientRMI.java
import java.rmi.*;
public class SimpleClientRMI {
public static void main(String argv[]) throws Exception
{
String url=rmi://localhost/SERVIDOR;
InterfaceRMI remoto;
remoto=(InterfaceRMI)Naming.lookup( url );
String dato=remoto.getDato();
System.out.println( dato );
}
}
71
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
COMPILACION Y CORRIDA
S
K
S E
CLIENTE T L SERVER
RMI U E RMI
B T
O
N
72
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
10. ACCESO A BASES DE DATOS
JDBC API - Java Database Connectivity Application Programming Interface
JDBC provee una interface estndar para acceder a bases de datos relacionales. Mediante las clases
incluidas en el paquete java.sql se pueden ejecutar querys, updates, llamar a stored procedures y ejecutar
sentencias preparadas.
JDBC
ORACLE,
Programa JDBC INFORMIX,
Java otras...
.dbf
JDBC ODBC .txt
.xls
JDBC
Instancia el driver
Class.forName()
Creo un sentencia
Connection con
Statement stm
ResultSetMetaData rsmd
73
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
SimpleSelect.java
import java.sql.*;
public class SimpleSelect
{
public static void main(String args[]) throws Exception
{
String user= scott;
String passwd= tiger;
String driver=oracle.jdbc.driver.OracleDriver;
String url=jdbc:oracle:thin:@localhost:1521:orcl;
// para acceder a ODBC se deben utilizar estas lineas
// String driver=sun.jdbc.odbc.JdbcOdbcDriver;
// String url=jdbc:odbc:DATA_SOURCE_NAME;
Class.forName(driver);
Connection con=DriverManager.getConnection(url,user,passwd);
Statement stmt=con.createStatement();
String query= SELECT * FROM dept;
ResultSet rs=stmt.executeQuery(query);
ResultSetMetaData rsmd=rs.getMetaData();
int cantCols=rsmd.getColumnCount();
String campoi;
En SQL todos los ndices
boolean more=rs.next(); comienzan desde 1.
while( more )
{
for( int i=1; i <= cantCols; i++ )
{
campoi=rs.getString(i);
System.out.print(campoi+((i<cantCols)?, : ));
}
System.out.println();
more=rs.next();
}
rs.close();
stmt.close();
con.close();
}
}
74
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
API java.sql.ResultSetMetaData
public int getColumnCount()
public String getColumnLabel(int columnindex)
public String getColumnName(int columnindex)
public int getColumnType(int columnindex)
API java.sql.Statement
public ResultSet executeQuery(String sqlquery)
public int executeUpdate(String sqlupdate)
SimpleUpdate.java
import java.sql.*;
Statement stmt=con.createStatement();
String update= args[0];
int rtdo=stmt.executeUpdate(update);
stm.close();
con.close();
}
}
API java.sql.Connection
JDBC por default tiene
public void commit() setAutoCommit()=true.
public void rollback()
public void setAutoCommit(boolean b)
public CallableStatement prepareCall(String prepcall)
public PreparedStatement prepareStatement(String prepstm)
75
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
SimplePrepared.java
import java.sql.*;
PreparedStatement pstm;
pstm=con.prepareStatement(sprep);
pstm.setInt(1,10);
pstm.setInt(2,50);
pstm.execute();
pstm.close();
:
}
}
API java.sql.PreparedStatement
public void setInt(int index, int intvalue)
public void setString(int index, String stringvalue)
public void setNull(int index, int sqltype)
public boolean execute()
public ResultSet executeQuery()
public int executeUpdate()
76
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
11. GENERACION DINAMICA DE PAGINAS WEB
El desarrollo de software tiende a que cada vez la capa de presentacin (para sistemas basados en web)
sea mas liviana. En lo posible se busca que sea solo texto HTML. Si bien los applets son extremadamente
livianos, resultan demasiado pesados comparados con texto HTML.
Las soluciones Java para la generacin dinmica de pginas web son:
Java Servlets
Java ServerPages
Los servlets son programas Java con un ciclo de vida comparable al de un applet pero corriendo del lado
del servidor. Un servlet es semejante a un programa CGI: recibe un requerimiento HTTP y devuelve una
respuesta HTTP. Pero aqu termina la comparacin. A diferencia de los CGI que expanden un nuevo
proceso de sistema operativo los servlets se desarrollan a travs de threads, que son ms livianos y
consumen menos recursos, y al ser programas Java son totalmente independientes de la plataforma.
JSP combina HTML o XML con cdigo Java que utiliza para generar dinmicamente partes de la pgina.
Las pginas JSP se compilan en servlets. Son un nivel mas alto de programacin que los servlets y
permiten fcilmente separar la lgica de presentacin de la lgica de la aplicacin.
JAVA SERVLETS
HolaMundoServlet.java
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
77
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Para poder ejecutar este servlet necesitamos un web-server. Simplemente debemos copiar el .class al
directorio indicado (o configurado) para que residan los servlets y luego invocarlo desde un navegador
tipeando el URL correcto.
Bsicamente un servlet no es mas que una clase Java que implementa la interface Servlet. Muchas de las
tareas involucradas al responder a un requerimiento del cliente se resuelven automticamente. Por
ejemplo la multiprogramacin; los requerimientos concurrentes que surgen desde diferentes browsers
sobre el mismo servlet son derivados en threads.
As como un applet corre dentro del contexto del Web Browser, el Servlet corre dentro del contexto del
Servlet Engine (implementado por el web-server). Tanto el Browser como el Servlet Engine tienen una
Maquina Virtual Java corriendo continuamente. A diferencia de los applets, los servlets no usan ningn
tipo de interface grfica, como las clases del paquete java.awt pero tienen un acceso total al resto de la
API Java: JDBC, RMI, Sockets, Serializacin de Objetos, estructuras de datos como Vectores,
Hashtables, etc.
HTTP Servlets
En general nuestros servlets extendern a la clase HTTPServlet, que implementa la interface Servlet.
Heredando de esta clase los servlets adquieren una mayor funcionalidad. Por ejemplo se tiene fcil
acceso a los parmetros (GET o POST) pasados desde el browser al web-server. Similarmente, la salida
del servlet (pgina HTML generada dinmicamente) es enviada al Browser.
78
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
HolaMundoServlet2.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
79
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Aspectos Principales de los Servlets
El servlet se instancia una sola vez. Si recibe mltiples requerimientos simultneos sern delegados en
threads. El servlet engine mantiene una nica instancia de la clase resultando as un efecto de
persistencia de las variables de instancia. Mltiples requerimientos corrern en threads pero sobre la
misma instancia.
Contador1.java
public class Contador1 extends HttpServlet
{
private int contador=0;
public void doGet(
HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = new PrintWriter (response.getOutputStream());
out.println("<html>");
out.println("<body> Contador="+contador++);
out.println("</body></html>");
out.close();
}
}
80
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Ciclo de vida de un Servlet
El servlet tiene un ciclo de vida similar al de un Applet. Cuando es instanciado se le ejecuta el mtodo
init(). Mientras esta activo se ejecutaran sus mtodos doGet() o doPost() segn el mtodo HTTP que se
este utilizando. Por ltimo, cuando muere se ejecuta el mtodo destroy().
El servlet engine llama al mtodo destroy() cuando finalizaron todas las llamadas al mtodo service() o
bien al cabo de un cierto periodo de tiempo.
En principio podemos decir que el mtodo init() es un buen momento para tomar recursos tales como una
conexin la una base de datos, y que el mtodo destroy() es un buen momento para dejarlos. El problema
es que los diferentes requerimientos (muy posiblemente concurrentes) que le llegan al servlet son
manejados como threads sobre la misma instancia. Por lo tanto manejar un objeto de tipo Connection
(por ejemplo) como variable de instancia no es una buena idea. Recordemos que en la clase Connection
tenemos los mtodos commit() y rollback(). No habra problemas si solo utilizamos la conexin para
realizar consultas, pero si pretendemos realizar transacciones estaramos en un caso no thread safe
(inseguro para manejo de threads). Es decir: un thread podra estar insertando filas en diferentes tablas y
otro podra estar ejecutando el mtodo commit() simultneamente.
SingleThreadModel
Implementando esta interface (que no tiene mtodos) nos aseguramos de que el servlet manejar solo un
requerimiento a la vez. Java nos garantiza que no habr mas de un thread ejecutando el mtodo service()
del servlet a la vez. El servlet engine mantiene un pool de instancias del servlet y a cada requerimiento
concurrente le asigna una instancia distinta. Implementando esta interface el servlet ser thread safe.
Sin embargo no se resuelve el problema del acceso a los recursos comunes a todas las instancias como ser
las variables y mtodos estticos.
TestThread.java
public class TestThread extends HttpServlet implements SingleThreadModel
{
private static int continstancias=0; El servlet engine asignara una nueva
instancia del servlet para cada nuevo
public TestThread() requerimiento concurrente sobre el
{ mtodo service().
continstancias++;
} Cada vez que se cree una instancia
de esta clase incrementamos el
public void finalize() valor del contador
{
continstancias--; Cada vez que se elimine una
} instancia decrementamos el contador
81
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
String sdormir=request.getParameter(dormir);
if( sdormir==null)
{
out.println(Dormir (milisegundos):);
out.println(<form method=\"GET\" action=\"http://192.168.4.1:8080/servlet/TestThread\">);
out.println(<input type=\TEXT\ name=\dormir\>);
out.println(<input type=\submit\ value=\Enviar\>);
out.println(</form>);
}
else Duermo por sdormir milisegundos y
{ muestro el valor del contador.
try
{
Thread.sleep( Integer.parseInt(sdormir) );
out.println("<h1><CENTER> Cantidad de
instancias:"+continstancias+"</center></h1>");
}
catch( Exception ex)
{
ex.printStackTrace();
}
}
out.println("</body>");
out.println("</html>");
out.close();
}
}
1. Abrir el browser e invocar al servlet con una pequea cantidad de milisegundos. Veremos que el
contador esta en 1.
2. Recargar la pgina. Veremos que el contador sigue en 1. Esto quiere decir que no se creo una nueva
instancia. Evidentemente no fue necesario ya que hasta ahora no tuvimos requerimientos
concurrentes sobre el servlet.
3. Abrir otro browser e invocar al servlet con 30000 milisegundos (30 segundos). Mientras tanto en el
browser anterior vamos a invocar al servlet con 2000 milisegundos. Ahora si tendremos
requerimientos concurrentes. Veremos que el valor del contador se incremento.
4. Si abrimos otro browser y probamos con tres requerimientos concurrentes veremos que el servlet
engine creara una nueva instancia.
82
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
JAVA SERVER PAGES
Una pgina JSP permite combinar cdigo de marcacin como HTML o XML con lenguaje Java. En
principio, renombrando cualquier pgina .html como .jsp tenemos nuestra primer pgina JSP.
La pgina JSP reside en el web-server. Cuando se invoca por primera vez se genera como servlet, se
compilada y se instancia. Luego tiene un ciclo de vida anlogo al de los servlets. De hecho, es en servlet.
El siguiente ejemplo, al ser invocado muestra una pgina con los primeros 10 nmeros naturales.
Ejemplo2.jsp
out es uno de los objetos implcitos
<HTML> de los que disponemos dentro de los
<BODY> <center> <h1> scriptles.
Representa el PrintWriter out que
<% utilizamos en los servlets.
for( int i=0; i<10;i++)
{ Los objetos implcitos que existen
out.println( i + <br>); dentro de los scriptles son: request,
} response, out, exception y session
%>
</BODY> </center> </h1>
</HTML>
83
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
A continuacin veremos la versin JSP del servlet HolaMundoServlet2 que analizamos anteriormente. El
resultado es exactamente el mismo, pero el cdigo es mucho mas corto y mas simple.
HolaMundoJSP2.jsp
Declaraciones: permiten definir
<HTML> variables Java para utilizarlas a lo
largo de la pgina.
<BODY>
<%! String snombre; %> Request, otro de los objetos implcitos en los scriptles
En este ejemplo estamos utilizando declaraciones, expresiones y scriptles. Son algunas de las
posibilidades que nos brinda JSP.
Marca Comentario
Declaraciones <%! ... %> Permiten definir variables Java para utilizarlas a lo largo de la pgina.
Expresiones <%= ... %> Permiten visualizar como texto el valor de una variable.
JSP Y JavaBeans
El problema de los Servlets es que mezclan dos lenguajes: Java y HTML. Un diseador grfico no puede
escribir un servlet porque no tiene los conocimientos necesarios de Java. Anlogamente un programador
Java se ve limitado a la hora de escribir un servlet porque (muy probablemente) no tenga los
conocimientos necesarios de HTML y/o de diseo grfico para poder generar la salida del servlet.
JSP soluciona este problema permitiendo utilizar JavaBeans.
84
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
Un JavaBean (o simplemente un Bean) es un componente Java que encapsula cierta lgica de
programacin. Desde el punto de vista del programador, un bean no es mas que una clase Java que
respeta las convenciones de nomenclatura que explicamos en el capitulo programacin orientada a
objetos. Es decir:
Cualquier clase Java que cumpla con estas condiciones pueden considerarse un Bean.
BeanCount.java
Como podemos ver no tiene
public class BeanCount absolutamente nada nuevo. Es
{ una clase como cualquier otra.
private int contador=0;
public int getContador()
{
return ++contador;
}
public void setContador(int c)
{
contador=c;
}
}
Para el bean anterior, cada vez que se le requiera la propiedad contador (mediante el mtodo
getContador()) retornara el valor incrementado del contador.
Veremos ahora como desde una pgina JSP se puede utilizar este bean sin tener que escribir ni una sola
lnea de cdigo Java.
Los posibles alcances son:
TestBean.jsp application, session, request
y page
<html>
<body>
<jsp:useBean id= mibean scope=session class=BeanCount/>
<jsp:setProperty name=mibean property=contador value=0 />
<h1><center>
<jsp:getProperty name=mibean property=contador />
</center></h1>
</body>
</html>
Como vemos, separamos totalmente la lgica de la aplicacin de la lgica de presentacin. Esto permite
maximizar la productividad ya que cada desarrollador puede concentrarse en lo suyo. El programador
Java solo trabaja con cdigo Java. El programador HTML solo trabaja con cdigo HTML.
85
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
A continuacin analizaremos los tags useBean, setProperty y getProperty.
El siguiente ejemplo muestra como utilizando JSP, un programador HTML puede generar contenidos
dinmicos, accediendo a una base de datos sin conocer en detalle Java.
86
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
TestSQL.jsp
<html>
<body>
<jsp:useBean id=misql scope=session class=BeanSQL/>
<jsp:setProperty name=misql property=query value=select * from emp/>
<table border="2">
<% for( int i=0; i<misql.getCantFilas(); i++ ) { %>
<tr>
<% for( int j=0; j<misql.getCantColumnas(); j++ ) { %>
<td> <%= misql.getCelda(i,j) %> </td>
<% } %>
</tr>
<%} %>
</table>
</body>
</html>
TestSQL.jsp (versin 2)
<html>
<body>
<jsp:useBean id=misql scope=session class=BeanSQL/>
<jsp:setProperty name=misql property=query value=select * from emp/>
<%
for( int i=0; i<misql.getCantFilas(); i++ )
{
out.println(<table border=2>)
out.println(<tr>);
for( int j=0; j<misql.getCantColumnas(); j++ )
{
out.println(<td> + misql.getCelda(i,j) + </td>);
}
out.println(</tr>);
}
out.println(</table>);
%>
</body>
</html>
87
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
El resultado que obtenemos al invocar esta pgina es el siguiente.
BeanSQL.java
import java.sql.*;
import java.util.Vector;
public class BeanSQL
{
private Connection con=null;
private String query=null;
private int cantColumnas;
private Vector vResultado;
public BeanSQL() throws Exception
{
String url=jdbc:oracle:thin:@localhost:1521:oracl;
String user=scott;
String password=tiger;
String driver=oracle.jdbc.driver.OracleDriver;
Class.forName(driver);
con=DriverManager.getConnection(url,user,password);
}
public String getQuery() throws Exception { return query; }
public int getCantColumnas() { return cantColumnas; }
public int getCantFilas() { return vResultado.size(); }
public String getCelda(int f,int c) { return ((String[])vResultado.elementAt(f))[c]; }
88
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
public void finalize()
{
try{
con.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
public void setQuery(String q) throws Exception
{
query=q;
_ejecutar();
}
private void _ejecutar() throws Exception
{
vResultado=new Vector();
Statement stm=con.createStatement();
ResultSet rs=stm.executeQuery(query);
ResultSetMetaData rsmd=rs.getMetaData();
int cantCols=rsmd.getColumnCount();
cantColumnas=cantCols;
String reg[];
boolean more=rs.next();
while( more )
{
reg=new String[cantCols];
for( int i=1; i<=cantCols; i++ )
{
reg[i-1]=rs.getString(i);
}
vResultado.addElement(reg);
more=rs.next();
}
rs.close();
stm.close();
}
}
89
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
APENDICE SQLJ
SQLJ Cdigo SQL embebido en cdigo Java
Con SQLJ podemos embeber directamente cdigo SQL en el cdigo Java. Los archivos deben ser .sqlj.
El SQLJ translator precompila el archivo .sqlj generando un archivo .java con sentencias JDBC. Luego
se compila normalmente para obtener el .class.
SimpleSQL.sqlj
import sqlj.runtime.*;
import sqlj.runtime.ref.*;
import oracle.sqlj.runtime.*;
import java.sql.*;
public class SimpleSQL
{
public static void main(String args[]) throws Exception
{
String url="jdbc:oracle:thin:@localhost:1521:pablo";
String driver="oracle.jdbc.driver.OracleDriver";
String user="scott";
String passwd="tiger";
Class.forName(driver);
Connection con; con=DriverManager.getConnection(url,user,passwd);
String sname;
Especifica el contexto contra
Oracle.connect(con); el que se ejecutaran las
sentencias SQL
#sql { SELECT ename
INTO :sname
FROM emp
WHERE empno=7369 };
con.close();
System.out.println(sname);
}
}
90
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
COMPILACION Y CORRIDA
c:\> sqlj SimpleSQL.sqlj
The system detects that Oracle was installed under dir
D:\Oracle\Ora81
If it is correct, enter Y; Otherwise, enter N (Y/n) y
c:\> dir
SimpleSQL.class
SimpleSQL.java
SimpleSQL.sqlj
SimpleSQL_SJProfile0.ser
SimpleSQL_SJProfileKeys.class
JDBC SQLJ
Ventajas No requiere Cdigo muy simple.
precompilador. Puede precompilar verificando on-
Acepta SQL dinmico. line la consistencia del cdigo
contra la base de datos.
COMPILACION Y CORRIDA 2
c:\> sqlj user scott/tiger SimpleSQL.sqlj
SimpleSQL.sqlj:21.5-23.38: Warning: Unable to check WHERE clause. Error returned
by database is: ORA-00904: nombre de columna invlido
UPDATE
#sql { UPDATE emp SET sal=3000 WHERE ename= SCOTT };
#sql { COMMIT };
SELECT Y UPDATE
String name= SCOTT;
Double raise=new Double(1.08);
Double salary;
#sql { UPDATE emp SET sal=sal* :raise WHERE ename= :name };
#sql { SELECT sal INTO :salary FROM emp WHERE ename=:name};
91
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
EXPRESIONES JAVA CON SQL
while( j<emps.length )
{
#sql { SELECT sal INTO :(s[j]) FROM emp
WHERE ename=:(emps[j].toUpperCase()) };
}
String en10dias;
#sql en10dias={ VALUES( DELTA_DATE(:today,10) ) };
System.out.println(y dentro de 10 dias sera:+en10dias);
STORED PROCEDURES
int x=10, y, z=20;
#sql { CALL MyProc( :x, :OUT y, :INOUT z) };
92
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar
CURSORES
#sql iterator NamedIterator(String ename,Double sal);
NamedIterator n;
#sql n = { SELECT ename, sal FROM emp };
while( n.next() )
{
System.out.println( Nombre=+n.ename() + Salario=+n.sal());
}
n.close();
String pnombre=null;
Double psal=null;
#sql iterator MyCursor(String , Double );
MyCursor n;
#sql n={ SELECT ename,sal FROM emp };
while( true )
{
#sql { FETCH :n INTO :pnombre,:psal };
if( n.endFetch() )
{
break;
}
System.out.println(pnombre + + psal);
}
n.close();
93
Pablo Augusto Sznajdleder cel. 15-4419-JAVA (5282)
Ing. en Sistemas de Informacin Cert i f i ed Devel oper e.mail. pablosz@pablosz.com.ar