Vous êtes sur la page 1sur 108

Introduccin

Rodrigo Lopez

Introduccin

Table of Contents
Java a Vuelo de Pjaro.......................................................................................................................................1 Caractersticas..........................................................................................................................................1 Algo de Historia.......................................................................................................................................1 Minisintaxis de Java .................................................................................................................................2 Un Programa Java....................................................................................................................................4 Referencias ...............................................................................................................................................5 Introduccin a Programacin Orientada por Objetos....................................................................................6 Especificacin de un problema................................................................................................................6 Cambio en la especificacin..............................................................................................................7 Malentendido en la especificacin....................................................................................................7 Diseo de una clase ..................................................................................................................................8 Una clase no es un objeto .........................................................................................................................9 Procesamiento de Java.....................................................................................................................................10 Compilacin...........................................................................................................................................10 Ejecucin ................................................................................................................................................11 Empaque................................................................................................................................................11 Documentacin Javadoc........................................................................................................................12 Variables y Objetos...........................................................................................................................................13 Variables................................................................................................................................................13 Objetos...................................................................................................................................................14 Comportamiento de los Objetos......................................................................................................16 Constructores...................................................................................................................................18 Visibilidad..........................................................................................................................................................20 Paquetes.................................................................................................................................................20 Control de Acceso..................................................................................................................................21 Encapsulamiento....................................................................................................................................23 Tiempo de vida......................................................................................................................................23 Modificador final...................................................................................................................................24 Herencia y Polimorfismo..................................................................................................................................26 Polimorfismo.........................................................................................................................................27 Clases Abstractas...................................................................................................................................28 Interfaces................................................................................................................................................29 Manejo de Excepciones .....................................................................................................................................34 Definicin de Excepciones....................................................................................................................36 Encadenamiento de Excepciones...........................................................................................................36 Aserciones..............................................................................................................................................36 Conociendo el JDK...........................................................................................................................................38 java.lang.String......................................................................................................................................38 Comparaciones................................................................................................................................39 El mtodo toString()........................................................................................................................39 Manejo de Fechas..................................................................................................................................40 i

Introduccin

Table of Contents
Conociendo el JDK Date.................................................................................................................................................40 Calendar..........................................................................................................................................40 . Mtodos comunes a todos los objetos ....................................................................................................41 toString().........................................................................................................................................41 equals()............................................................................................................................................42 hashCode()......................................................................................................................................42 . clone() ..............................................................................................................................................43 Colecciones............................................................................................................................................44 Arreglos...........................................................................................................................................44 Interface List...................................................................................................................................44 . Interface Set ....................................................................................................................................46 . Interface Map..................................................................................................................................47 Ordenamientos .................................................................................................................................48 Formateadores........................................................................................................................................49 DecimalFormat................................................................................................................................49 SimpleDateFormat..........................................................................................................................50 . System....................................................................................................................................................50 Receta para hashCode()...................................................................................................................................52 Entrada/Salida ...................................................................................................................................................53 Flujos.....................................................................................................................................................53 java.io.InputStream................................................................................................................................53 java.io.OutputStream.............................................................................................................................53 Decoracin de flujos..............................................................................................................................56 Manejo de archivos ZIP.........................................................................................................................57 Flujos de texto........................................................................................................................................58 Serializacin .......................................................................................................................................................60 Flujos de Objetos..................................................................................................................................60 Flujos de bytes......................................................................................................................................61 Flujos de caracteres...............................................................................................................................62 Archivos de Propiedades..................................................................................................................................64 El sistema de archivos.......................................................................................................................................65 Mtodos.................................................................................................................................................65 Carga de Recursos ..................................................................................................................................66 Swing..................................................................................................................................................................68 Historia ...................................................................................................................................................68 Componentes pesados vs. Componentes livianos .................................................................................68 SWING y AWT....................................................................................................................................69 Manejo de Eventos ................................................................................................................................70 Ejemplo simple...............................................................................................................................71 Un ejemplo ms complicado..........................................................................................................71 Interfaz de oyente de varios mtodos.............................................................................................72 ii

Introduccin

Table of Contents
Swing Los Eventos ...........................................................................................................................................72 Construccin de event listeners............................................................................................................73 Clases internas......................................................................................................................................74 Clases internas annimas......................................................................................................................74 El patrn "Observer"..............................................................................................................................75 Java Beans y POJOs.........................................................................................................................................76 Propiedades............................................................................................................................................76 Propiedades Booleanas....................................................................................................................77 Propiedades indexadas....................................................................................................................78 Manejo de Propiedades..........................................................................................................................78 Commons BeanUtils ........................................................................................................................78 Reflexin en Java...................................................................................................................................79 Paralelismo........................................................................................................................................................82 MultiTasking.........................................................................................................................................82 MultiThreading......................................................................................................................................82 Threads en Java......................................................................................................................................82 Sincronizacin ........................................................................................................................................84 Java 1.5 ...............................................................................................................................................................85 AutoBoxing............................................................................................................................................85 Enumeraciones.......................................................................................................................................85 Genericidad............................................................................................................................................87 Interfaz Iterable...............................................................................................................................89 Sorpresas.........................................................................................................................................90 Import esttico.......................................................................................................................................91 Nmero variable de argumentos............................................................................................................92 Anotaciones ............................................................................................................................................93 Definicin de Anotaciones..............................................................................................................94 Ejemplo...........................................................................................................................................94 Log4J..................................................................................................................................................................97 Receta Global para usar Log4J..............................................................................................................98 Arquitectura...........................................................................................................................................98 Jerarqua de Loggers.......................................................................................................................99 Niveles.............................................................................................................................................99 Appenders ......................................................................................................................................101 Layouts..........................................................................................................................................102 Configuracin......................................................................................................................................103 Configuracin en XML.................................................................................................................103

iii

Java a Vuelo de Pjaro


Caractersticas
Orientado por objetos. Cdigo mvil Computacin basada en la red. Write once, run everywhere. El fuente java se compila hacia un bytecode El bytecode es ejecutado por la Mquina Virtual de Java (JVM)

Algo de Historia
Desarrollado entre 1991 y 1995 Lanzado oficialmente en enero de 1996 Versiones: JDK 1.02 (1996): primer lanzamiento, applets, 250 clases, lento. JDK 1.1 (1997): reestructuracin de eventos AWT, clases internas, JavaBeans, JDBC (Java Data base Connectivity), RMI(Remote Method Invocation), 500 clases, algo ms rpido. J2SE 1.2 (1998): Nombre clave Playground. Tambin llamado Java 2, incluye los "sabores" J2EE y J2ME. Palabra reservada strictfp, reflexin, Swing, compilador JIT, Java IDL, Colecciones. J2SE 1.3 (2000): Nombre clave Kestrel. Hotspot JVM, JNDI, JPDA (Java Platform Debugger Architecture). Java a Vuelo de Pjaro 1

Introduccin J2SE 1.4 (2002): Nombre clave Merlin, palabra reservada assert, expresiones regulares, encadenamiento de excepciones, nuevos mecanismos de entrada/salida, API para logging, JAXP, seguridad y extensiones criptogrficas, Java Web Start, 2300 clases. J2SE 5.0 (2004): Nombre clave Tiger. Tipos genricos, anotaciones, autoboxing, palabra reservada enum, nmero variable de argumentos, formatos para impresin, sintaxis mejorada para las iteraciones for, 3500 clases. Java SE 6 (2006): Nombre clave Mustang. Motores de lenguajes de script embebidos (Ruby, Groof, BeanShell, Rhino), soporta las ltimas especificaciones de servicios Web (JAX-WS 2.0, JAXB 2.0, STAX y JAXP), base de datos embebida (Derby). En el 2005 se estimaba que haba 4.5 millones de desarrolladores Java y 2.5 millones de dispositivos habilitados con tecnologa Java. Sun Microsystems liber una buena parte de su tecnologa Java bajo licencia GNU GPL y de acuerdo con las especificaciones del Java Community Process.

Minisintaxis de Java
Una clase (pblica) se define en un archivo fuente cuyo nombre es igual al de la clase, con la extensin .java
ARCHIVO Perro.java public class Perro{ }

Una clase tiene uno o ms mtodos


ARCHIVO Perro.java public class Perro{ public void ladrar(){ } }

Una clase puede tener uno o ms atributos o variables de instancia.


ARCHIVO Perro.java public class Perro{ public float peso; public void ladrar(){ } }

Dentro de un mtodo hay instrucciones y declaraciones de variables.

Algo de Historia

Introduccin
ARCHIVO Perro.java public class Perro{ public float peso; public void ladrar(){ float volLadrido; instr_1 ; instr_2 ; } }

Toda instruccin termina en punto y coma (;)


x = x + 2;

Las variables se declaran con un nombre y un tipo


int x;

Tipos primitivos: boolean, char, byte, short, int, long, float, double. Los comentarios en una lnea comienzan con doble slash
int x; // declara a x como entero

Iteraciones: while, for, do-while


int x = 1; while(x <5) { x = x + 1; }

Instruccin condicional
if(x

if(x

Operadores de comparacin: < (menor que), >(mayor que), == (igualdad), != (diferente)


boolean b = x != y; if(a == 5) { // ...}

Operadores booleanos: ! (not), && (and), || (or)

if(a && b) { //La evaluacin de b es condicional !! }

Minisintaxis de Java

Introduccin
if(!a) { }

Operadores aritmticos: +, -, *, /, %
boolean a; a = 17 % 5 == 2;

Operadores de incremento y decremento: ++,-int x = 8; x++; //Incrementa a x x--; //Decrementa a x

for(int x=1; x

Creacin de objetos de una clase: operador new


Perro mao = new Perro();

Invocacin de mtodos
Perro mao = new Perro(); mao.ladrar();

Acceso a los atributos de un objeto


Perro mao = new Perro(); float z = 34.5 + mao.peso;

Un Programa Java
Conjunto de clases. Tpicamente un archivo fuente (.java) por clase. La ejecucin comienza por el mtodo main de una de las clases. Hello.java Compilacin de un programa.
$ javac Hello.java

Un Programa Java

Introduccin Ejecucin de un programa


$ java Hello

Referencias
Head First Java (2nd edition) Editorial O'Reilly (2005) Kathy Sierra & Bert Bates Thinking in Java (4th edition) Prentice Hall (2006) Bruce Eckel

Referencias

Introduccin a Programacin Orientada por Objetos


Especificacin de un problema
Hay tres figuras en una interfaz grfica: un cuadrado, un crculo y un tringulo. Cuando el usuario da click sobre una figura, la figura debe rotar 360 grados en el sentido de las agujas del reloj produciendo un ruido especfico para cada figura y que est grabado en un archivo AIF.

PROGRAMADOR PROCEDIMENTAL procedure rotar(int codForma) { // Hacer rotar la figura de cdigo "codForma"; } procedure hacerRuido(int codForma){ //Usar el codForma para buscar el archivo //AIF correspondiente y hacerlo sonar. } PROGRAMADOR OO class Cuadrado{ rotar() { //rotar el cuadrado } hacerRuido(){ //hacer sonar el ruido del cuadrado } } class Tringulo{ rotar() { //rotar el tringulo } hacerRuido(){ //hacer sonar el ruido del tringulo } } class Crculo{ rotar() { //rotar el Crculo }

Introduccin a Programacin Orientada por Objetos

Introduccin
hacerRuido(){ //hacer sonar el ruido del Crculo } }

Cambio en la especificacin
Adems hay una amiba en la pantalla. Si el usuario da click sobre ella, tambin debe rotar pero el ruido est grabado como un archivo .HIF

PROGRAMADOR PROCEDIMENTAL procedure rotar(int codForma) { // Hacer rotar la forma de cdigo "codForma"; } procedure hacerRuido(int codForma){ //if codForma no es el de la amiba //Usar el codForma para buscar el archivo //AIF correspondiente y hacerlo sonar. //else //tocar amiba.hif } PROGRAMADOR OO class Amiba{ rotar() { //rotar la amiba } hacerRuido(){ //hacer sonar el ruido de la amiba } }

Malentendido en la especificacin
Los programadores hicieron rotar cada figura as: Se determina el rectngulo que circunscribe a la figura. Se hace rotar el rectngulo alrededor de su centro. Especificacin de un problema 7

Introduccin pero: La amiba debe rotar alrededor de su "extremo derecho".


PROGRAMADOR PROCEDIMENTAL procedure rotar(int codForma) { // if la forma no es una amiba // calcule el centro del rectangulo // then rote // else // Calcule las coordenadas del extremo derecho // then rote } procedure hacerRuido(int codForma){ //if codForma no es el de la amiba //Usar el codForma para buscar el archivo //AIF correspondiente y hacerlo sonar. //else //tocar amiba.hif } PROGRAMADOR OO

Abstrae las cosas comunes a las figuras y las coloca en una nueva clase "Forma"

Forma es la superclase de las otras 4 clases. Las otras cuatro son subclases de Forma. Las subclases heredan los mtodos de la superclase.

Diseo de una clase


Hay que pensar en las caractersticas de los objetos de esa clase: Aquello que el objeto conoce (sabe acerca de s mismo): Atributos, variables de instancia, variables de estado.

Malentendido en la especificacin

Introduccin Suelen tener valores diferentes para cada objeto o instancia de la clase. Pueden influir en el comportamiento del objeto. Las cosas que hace: Mtodos (comportamiento).
class Perro { tamao; raza; nombre; ladrar() { } }

Una clase no es un objeto


Una clase define una categora (un tipo) de objetos. Es un patrn para la construccin de los objetos (instancias) de esa clase. Cada objeto puede tener sus propios valores para los atributos o variables de instancia. Todos los objetos comparten los mismos mtodos Juego de adivinanza

Diseo de una clase

Procesamiento de Java
Dos escenarios tpicos: compilacin y ejecucin

JDK: Java Development Kit. JRE: Java Runtime Environment.

Compilacin
El compilador requiere tener acceso a todas las clases o interfaces (fuentes o compiladas) mencionadas explcitamente en los fuentes.
$ javac -classpath ./uis:../lib/api.jar \ -d ./bin ./fuentes/*.java

El classpath de compilacin es uno de los dolores de cabeza de todos los programadores Java Procesamiento de Java 10

Introduccin Las libreras (.jar) pertenecientes al JRE se encuentran implcitamente dentro del classpath

Ejecucin
Todas las clases que deban ser cargadas durante la ejecucin de un programa deben ser accesibles por la Mquina Virtual. Las clases pertenecientes a las libreras del JRE son accesibles. Las dems libreras/clases deben ser especificadas en el classpath de ejecucin Las clases se van cargando a medida que se requieren.
$ java -classpath ./bin:../lib/api.jar:../lib/jakarta.jar com.cincosoft.Facturacion \

El classpath de ejecucin es una fuente inagotable de sorpresas ClassNotFound !! El mismo programa a veces falla y a veces no.

Empaque
Es cmodo empacar el conjunto de clases y otros recursos de un programa (o de una librera) en un archivo.
$ jar -cf miapplicacion.jar *.class

Usa el formato ZIP. Incluye un archivo MANIFEST.MF Se puede descomprimir.


$ jar -xvf miapplicacion.jar

Un programa se puede ejecutar en formato jar.


$ java -classpath miapplicacion.jar Miclase $ java -jar miapplicacion.jar

Dentro del MANIFEST.MF se especifica la clase que contiene el mtodo main Archivo MANIFEST.MF Main-Class : miclase

Compilacin

11

Introduccin

Documentacin Javadoc
Javadoc genera documentacin en formato Html a partir de comentarios /** ... */. Vlido para clases, atributos y mtodos. Crea referencias "vivas" entre los miembros de las clases documentadas. Permite referenciar documentos html arbitrarios: documentacin de paquetes o de toda una aplicacin.
$ javadoc [ options ] [ packagenames ] [ sourcefilenames ]

Juego de adivinanza Javadoc Las herramientas de procesamiento estndar se usan ms cmodamente desde ANT que desde la lnea de comandos.

Documentacin Javadoc

12

Variables y Objetos
Variables
Se declaran con un tipo y un nombre.
int x; Rueda r; float _Nombre_1;

La variable siempre conserva su tipo pero puede cambiar de valor mediante la asignacin
int x = 5; x = 8; byte b; b = x; //error!! x = (int) 17.4;

Las variables pueden verse como contenedores de valores. Pueden aparecer como: Atributos de clase. Variables locales de un mtodo. Argumentos de un mtodo. Solamente pueden almacenar dos tipos de valores. Valores primitivos.

Referencias a objetos.
Joystick j = new Joystick(); Rueda r = new Rueda();

Variables y Objetos

13

Introduccin

Las variables no almacenan objetos. Las variables se asignan, por valor (por copia).
int x = 5; int y; y = x; //tanto x como y contienen el valor 5 Rueda r = new Rueda(); Rueda t; t = r; // r y t referencian al mismo objeto Rueda. Joystick j = new Joystick(); j = r //error!!

Las variables locales y los argumentos de los mtodos "viven" en el stack de ejecucin de la mquina virtual. Se crean al entrar (en ejecucin) al mtodo que las contiene. Se destruyen al salir del mtodo que las contiene.

Objetos
Viven en el "heap". Son de tamaos diferentes Pueden contener referencias a otros objetos (variables) Variables 14

Introduccin
class Casa { Puerta p = new Puerta(); } :::: Casa c = new Casa();

Pueden convertirse en basura y ser recogidos por el garbage collector


void abrir(){ Casa c= new Casa(); c.p = null //la puerta se convierte en basura !! } //Al salir toda la casa es basura !!

Los arreglos son objetos.


int [] nums; nums = new int[5]; Perro [] p = new Perro[3]; p[2] = new Perro();

Objetos

15

Introduccin
String [] islas = {"Baru", "Gorgona"};

Los arreglos tienen longitud (el nmero de valores que contienen).


String [] islas = {"Baru", "Gorgona"}; for(int i =0; i <islas.length; i++) { System.out.println(islas[i]); }

Comportamiento de los Objetos


El comportamiento de los objetos est determinado por sus mtodos y (eventualmente) por su estado (variables de instancia).
class Perro{ int peso; String nombre; void ladrar() { System.out.printl("Guau, Guau"); } } class Perro{ int peso; String nombre; void ladrar() { if(peso > 25 ){

Comportamiento de los Objetos

16

Introduccin
System.out.printl("Woof, Woof"); } else if (peso > 15) { System.out.printl("Ruff, Ruff"); } else { System.out.printl("Guau, Guau"); } } }

Los mtodos pueden tener parmetros


class Perro{ int peso; String nombre; void ladrar() { if(peso > 25 ){ System.out.printl("Woof, Woof"); } else if (peso > 15) { System.out.printl("Ruff, Ruff"); } else { System.out.printl("Guau, Guau"); } } void ladrar(int numLadridos) { while (numLadridos > 0) { ladrar(); numLadridos--; } } void setPeso(int p) { peso = p; } } :::: Perro p = new Perro(); p.setPeso(18); p.ladrar(5);

Los mtodos pueden retornar un valor: Hay que declarar el tipo del valor de retorno. Es obligatorio "retornar" un valor del tipo declarado (o compatible con l)
int darNumero() { return 42; } ::: int valor = obj.darNumero(); long largo = obj.darNumero();

Comportamiento de los Objetos

17

Introduccin

Constructores
Los constructores son unos mtodos especiales cuya labor es construir los objetos (instancias) de la clase a la cual pertenecen: Su nombre es exactamente igual al nombre de la clase. No especifican el tipo del valor de retorno. Pueden tener parmetros.
public class Perro{ int peso; String nombre; public Perro(int p, String nombre) { peso = p; this.nombre = nombre } } ::: Perro p = new Perro(16,"Mao");

Si no se define ningn constructor, se supone que hay un constructor sin parmetros


public class Perro{ int peso; String nombre; } ::: Perro p = new Perro();

Si se define algn constructor y se requiere el constructor sin parmetros, es obligatorio definirlo


public class Perro{ int peso; String nombre; public Perro(int p, String nombre) { peso = p; this.nombre = nombre } } :::: Perro p = new Perro(); // error!! (constructor indefinido)

public class Perro{ int peso; String nombre;

Constructores

18

Introduccin
public Perro() { } public Perro(int p, String nombre) { peso = p; this.nombre = nombre } } :::: Perro p = new Perro(); // OK

Constructores

19

Visibilidad
Uno de los beneficios de la programacin Orientada por Objetos es la posibilidad de reutilizacin del software. No es conveniente que todo est disponible para ser reutilizado. Si el comportamiento de un objeto depende de su estado, es crucial poder garantizar que el estado no se altera "por descuido" o por ignorancia (del programador). Es conveniente poder limitar el acceso a las variables, a los mtodos y a las clases.

Paquetes
Un paquete es un conjunto de clases. Las clases que tienen un propsito comn suelen agruparse en un paquete. Cada clase declara el paquete al cual pertenece. La declaracin deber ser la primera lnea (distinta de comentario) del archivo fuente. Si no se declara paquete, la clase pertenece al paquete annimo El nombre del paquete hace parte del nombre de las clases que pertenecen al paquete.
package animales; public class Perro{ ::: } public class Prueba{ public static void main(String[] args){ animales.Perro p = new animales.Perro(); Perro can = new Perro(); //error!! la clase Perro no pertenece //al paquete anonimo } }

Los nombres de los paquetes suelen tener identificadores separados por un punto.
package com.cincosoft; package com.cincosoft.utils; package org;

Cuando se compila un conjunto de archivos fuente java, los archivos .class generados se almacenan en una jerarqua de directorios-subdirectorios que refleja la estructura de los nombres de los paquetes declarados en los fuentes.

Visibilidad

20

Introduccin

No existe la nocin de subpaquete!!. Algunos IDE's exigen organizar los fuentes reflejando la estructura de los paquetes.

Control de Acceso
Todos los atributos y mtodos de una clase son accesibles dentro del cuerpo de la clase. Las clases del mismo paquete son visibles entre s.
package entes; class Perro { }

package entes; class Joystick { void metodo() { Perro p = new Perro(); } }

Modificadores de acceso (visibilidad): public: ampla la visibilidad hacia afuera del paquete.

Paquetes

21

Introduccin
package animales; public class Perro { public int peso; ::: public void ladrar() { } }

package devices; import animales.Perro; class Joystick { void metodo() { Perro p = new Perro(); p.peso = 18; p.ladrar(); } }

private: restringe la visibilidad estrictamente al interior de la clase.


package entes; public class Joystick { private Baston baston; private void metodo() { Perro p = new Perro(); baston = null; BolitaJS bol = new BolitaJS(); } private class BolitaJS { } }

protected: visible dentro del mismo paquete y en las subclases de la clase en donde se declara (sin importar el paquete al que pertenezcan).
package figuras; public class Circulo { protected double radio; protected double area() { } }

package trigonometricas; public class CirculoUnitario extends Circulo{ public float metodo(){ this.radio; }

Control de Acceso

22

Introduccin
}

<sin-modificador>: visible dentro del paquete pero inaccesible por fuera del paquete (visibilidad "de paquete").

Encapsulamiento
En general, no es buena idea permitir acceso a los atributos de una clase que determinan aspectos cruciales del estado de los objetos. Deben declararse privados. Se permite el acceso en lectura o en escritura mediante mtodos pblicos.
public class Persona { private Date nacimiento; private String nombre; public Persona (Date d, String s){ this.nacimiento = d; this.nombre = s; } public Date getNacimiento(){ return nacimiento; } public void setNombre(String s){ nombre = s; } public String getNombre(){ return nombre; } }

Tiempo de vida
Durante la ejecucin de un programa, las variables y los objetos aparecen (se les reserva memoria) y desaparecen (se eliminan del stack o se recogen como basura). Las variables de instancia (atributos) existen mientras exista el objeto al cual pertenecen. Modificador static: hace el tiempo de vida independiente de las instancias. La vida comienza cuando se usa por primera vez la clase en la que aparece la variable o mtodo static (parecido a "variables globales").
public class Vaso { public static int numVasos = 0; private Forma forma; public Vaso() {

Encapsulamiento

23

Introduccin
numVasos++; ::: } } public class Comedor { private Comedor (int n) { } public static Comedor init() { ::: Comedor c = new Comedor(3); ::: return c; } } public class Casa { public Casa () { if(Vaso.numVasos > 0) { Comedor c = Comedor.init(); } }

public class Ensayo { private int x = 5; int calcular() { } public static void main(String [] args){ x = 3; //error: x es variable de instancia calcular(); //error: calcular() es metodo de instancia } } public class Vaso { public static int numVasos; private Forma forma; static { numVasos = (int) (Math.random() * 26); } public Vaso() { numVasos++; ::: } }

Modificador final
Impide la modificacin de la variable, mtodo, clase al cual modifica:

Tiempo de vida

24

Introduccin
public final class Inmutable { //No se puede extender } public class Nueva extends Inmutable { //error!!. Inmutable es final } final String saludo = "Hola"; saludo = "Hello"; //error!! saludo es final public static final double MAX_VOL = 35.8; //Constante de clase

public class AparatoElectrico { public final void prender() {//no se puede redefinir conectarCorriente(); } } public class Licuadora extends AparatoElectrico{ public void prender() {//error!! prender es final } }

Modificador final

25

Herencia y Polimorfismo

La subclase hereda los atributos y mtodos de su superclase (a menos que sean privados) La subclase no hereda los constructores de la superclase pero tiene acceso a ellos. La subclase extiende la superclase. Agrega atributos. Redefine mtodos Agrega mtodos. Todas las clases de un programa Java heredan implcitamente de la superclase java.lang.Object

public class Doctor { boolean trabajaEnHospital; void tratarPaciente () { // hace revision medicas } } public class MedicoFamiliar extends Doctor { boolean visitarDomicilio; public MedicoFamiliar(boolean domicilios) { super(); visitarDomicilio = domicilios; } void darConsejos() { //Mtodo agregado } }

Herencia y Polimorfismo

26

Introduccin
public class Cirujano extends Doctor { void tratarPaciente () { //Mtodo redefinido // hace cirujias } void suturar() { } }

Polimorfismo
Una variable del tipo de la superclase puede almacenar referencias a instancias de sus subclases.
Doctor doc = new Doctor(); Cirujano cir = new Cirujano(); MedicoFamiliar mf = new MedicoFamiliar(); doc = cir; //Un doctor puede ser un cirujano doc.tratarPaciente(); //El doctor hace cirujias doc = mf; //Un doctor puede ser un mdico familiar doc.tratarPaciente(); //El doctor hace una revisin mdica cir = doc; //error !! Un doctor no necesariamente //es un cirujano cir = (Cirujano) doc; //Como este doctor es un cirujano, OK if (doc instanceof Cirujano) { cir = (Cirujano) doc; }

La herencia, combinada con el polimorfismo permite: Ahorrar cdigo (evitando las duplicidades). Ahorrar muchos if's. Agregar ordenadamente muchos casos nuevos.
public class Neurocirujano extends Cirujano { public void tratarPaciente() { //operar con laser } } Cirujano cir; Doctor doc; NeuroCirujano nc = new NeuroCirujano(); doc = nc; cir = nc;

Polimorfismo

27

Introduccin
doc.tratarPaciente(); // Opera con laser cir.tratarPaciente(); // Opera con laser

En la prctica, las jerarquas de herencia no son muy profundas. Tres niveles es bastante.

Clases Abstractas
A veces, puede no tener sentido tener instancias de una clase. Los doctores pueden compartir muchas cosas (nominalmente) pero para cada uno, tratar al paciente es algo muy diferente. El MedicoFamiliar lo ausculta y receta. El Cirujano lo opera.
abstract class Doctor { boolean trabajaEnHospital; public abstract void tratarPaciente(); public void darConsejos() { //Metodo concreto } } class MedicoFamiliar extends Doctor {// Clase concreta public void tratarPaciente() { // Ausculta y receta } } class Urologo extends Doctor {//error!!. Urologo es abstracto void darConsejos() {

Clases Abstractas

28

Introduccin
} } abstract class Cirujano extends Doctor { void suturar() {// Metodo concreto //cose con hilo encerado } }

class Plastico extends Cirujano { //Clase concreta void tratarPaciente() { // hacer injertos } } class NeuroCirujano extends Cirujano { //Clase concreta void tratarPaciente () { // opera con laser } void suturar () { // sutura con laser } } ::: new Doctor().darConsejos(); // error!! Doctor es abstracto Doctor doc; Cirujano cir; cir = new Plastico(); cir.suturar(); // Cose con hilo encerado doc = new Neurocirujano(); doc.suturar(); cir.tratarPaciente();

Interfaces
Un programa java es un conjunto de clases, e instancias de clases, interactuando mediante la ejecucin de mtodos. Cada clase puede considerarse como un servidor y los servicios ms amplios que ofrece son sus mtodos pblicos. Ellos establecen un protocolo preciso (valor de retorno, parmetros que espera) de cmo deben ser utilizados por sus clientes. Ese conjunto de mtodos se denomina (en programacin OO) la interfaz de la clase. En Java, una interfaz es un conjunto de servicios.
public Iterface Sacristan {

Interfaces

29

Introduccin
public final int EDAD_MINIMA = 55; public void sonarCampanas(); public void recogerLimosna(); }

Una interfaz define un tipo. Una interfaz no se instancia. Una interfaz puede contener mtodos y atributos Los atributos son implcitamente final y static. Los mtodos son implcitamente public. Una interfaz puede ser implementada por una clase: debe definir todos los mtodos de la interfaz Una interfaz se puede extender mediante herencia.
class Paisano implements Sacristan { public void sonarCampanas() { } public void recogerLimosna(){ } } class NeuroCirujano extends Doctor implements Sacristan { //Todos los atributos y metodos de Neurocirujano ::: public void sonarCampanas() { } public void recogerLimosna(){ } } Sacristan sac; sac = new Sacristan(); // error!! NeuroCirujano nc = new NeuroCirujano(); sac = nc; nc.sonarCampanas(); // error!! sac.sonarCampanas(); Sacristan sac1 = new Paisano(); public void hacerOficio(Sacristan s) { s.sonarCampanas(); s.recogerLimosma();

Interfaces

30

Introduccin
} hacerOficio(new Paisano()); hacerOficio(new NeuroCirujano()); public Sacritan escoger() { if ( ...) { return new Paisano(); } else { return new NeuroCirujano(); } }

En java, una interfaz es muy parecida a una clase abstracta.


public abstract class SacristanAbs { public final int EDAD_MINIMA = 55; public abstract void sonarCampanas(); public abstract void recogerLimosna(); } public class Paisano extends SacristanAbs{ public void sonarCampanas() { } public void recogerLimosna(){ } } SacristanAbs sac = new Paisano(); sac.sonarCampanas(); //Pero no hay modo de que un NeuroCirujano sea //un SacristanAbs!! class NeuroCirujano extends Cirujano extends SacristanAbs {//error!! }

En general: Se define una clase abstracta A y una subclase B, si puede decirse que un B es siempre un A (Un NeuroCirujano es un Cirujano) Se define una interfaz A si se quiere que distintas clases puedan JUGAR EL ROL de A (Un NeuroCirujano puede jugar el rol de Sacristn)
public class NeuroCirujano extends Cirujano implements Sacristan implements Peluquero {

Interfaces

31

Introduccin
:::: } public class Madre implements Peluquero { } public class Paisano implements Peluquero { }

BUENA PRACTICA Es mejor programar contra interfaces que contra clases concretas

LinkedList lista = new LinkedList(); proceso(lista); public void proceso(LinkedList lis) { int i; ::: lis.get(i);

} LinkedList lista = new LinkedList(); :: proceso(lista); :: public void proceso(LinkedList lis) { int i; ::: while(..){ :: lis.get(i);//Se ejecuta varias veces

} } List lista = new ArrayList(); //List lista = new LinkedList(); :: proceso(lista); :: public void proceso(List lis) { int i; ::: while(..){ lis.get(i);//Se ejecuta varias veces

} }

Programando contra interfaces es menos traumtico cambiar la implementacin de los servicios. Interfaces 32

Introduccin Ejercicio

Interfaces

33

Manejo de Excepciones
Una excepcin es una indicacin de que una situacin excepcional se ha presentado o de que un error ha ocurrido. Se lanza una excepcin para indicar la situacin excepcional.

throw expresion;

Atrapar una excepcin es manejarla: tomar las acciones necesarias para recuperarse de ella.

try { //Alguna instruccin lanza una excepcin } catch (Exception e) { //Tratamiento de la excepcion } Ejemplo

Las excepciones son objetos.

Las "CheckedExceptions" que no sean atrapadas deben ser declaradas.

public String readFirstLine(String filename) throws IOException {

Manejo de Excepciones

34

Introduccin
BufferedReader in = new BufferedReader( new FileReader(filename)); return in.readLine(); }

Acciones al lanzar una excepcin: Se interrumpe la ejecucin del try en donde se lanza. Se contina la ejecucin en el primer catch que atrape la excepcin lanzada o una superclase de ella.
try { String s = readFirstLine("miarchivo.txt"); } catch(IOException e){ System.out.println(e.getMessage); } try { String s = readFirstLine("miarchivo.txt"); } catch(Exception e){// Atrapa cualquier excepcion e.printStackTrace(); }

A veces es necesario ejecutar una accin independientemente de si se lanza o no una excepcin


try { dbConnection = DAOUtil.getDBConnection(datasource); ps = dbConnection.prepareStatement(sbf.toString()); ps.setString(1,countryId); ps.executeQuery(); rs = ps.getResultSet(); while (rs.next()) { State state = new State(); state.setId(rs.getLong(1)); state.setCountryId(rs.getString(2)); state.setCode(rs.getString(3)); state.setName(rs.getString(4)); resp.add(state); } } catch (Exception ae) { logger.error("Error loading states", ae); throw new DAOException(ServicingExceptionMessage.PROBLEM_LOADING_STATES + ae.getMessage()); } finally { DAOUtil.closeResultSet(rs); DAOUtil.closePreparedStatement(ps);

Manejo de Excepciones

35

Introduccin
DAOUtil.closeConnection(dbConnection); }

Definicin de Excepciones
Se pueden definir excepciones extendiendo la clase Exception. Le da claridad a los programas.
public class PharosException extends Exception{ public PharosException(){} public PharosException(String s){ super(s); } } public class SearchException extends PharosException { public SearchException(String msg){ super(msg); } public SearchException(){} }

public class NullTaggedValueException extends PharosException{ public NullTaggedValueException(){} public NullTaggedValueException(String s){ super(s); } } if(tgVal==null || tgVal.getValue()==null){ throw new NullTaggedValueException(); }

Encadenamiento de Excepciones
Es frecuente atrapar una excepcin y, acto seguido, lanzar otra. Es muy valioso conservar informacin acerca de la excepcin atrapada originalmente
catch (Exception ae) { logger.error("Error loading states", ae); throw new DAOException(ae); }

Aserciones
Mecanismo para verificar dinmicamente el estado de un programa, lanzando excepciones si el estado no es el que se espera. Definicin de Excepciones 36

Introduccin
assert expresin-booleana ;

Si la expresin retorna false, se lanza el error AssertionError


assert expresin-booleana : objeto;

Si la expresin retorna false, se lanza el error AssertionError y se le pasa como argumento objeto.toString()
public long factorial(int x) { assert x >= 0 : "x debe ser mayor que 0"; long fact; for(fact=1; x > 1; fact *= x * x--); return fact; }

Para la ejecucin hay que activar explcitamente las aserciones. Se pueden quitar/poner sin necesidad de recompilar.
$ java -ea ClaseConAserciones

Aserciones

37

Conociendo el JDK
Las libreras del Java Development Kit contienen las clases bsicas accesibles implcitamente desde el classpath. Las clases del paquete java.lang son "importadas" implcitamente a cualquier programa.

java.lang.String
Representa las cadenas de caracteres en Java. Notacin de literales: sucesin de caracteres encerrados entre dobles comillas. No tiene que ser importada.
String x = "casa"; // char data [] = {'c','a','s','a'}; String y = new String(data);

Tiene mtodos para: Extraer subcadenas. Comparacin de cadenas. Bsqueda de subcadenas. Producir copias en mayscula/minscula. ... y muchos ms.
System.out.println("Un letrero"); String x = "casa"; if( x.compareTo("algo") > 1) { //comparacion lexicografica } String y = "Una cadena larga"; y.substring(4); //cadena larga y.substring(4,6); //cadena y.charAt(4); // 'c' y.indexOf("cadena"); //4 y.toUpperCase(); //UNA CADENA LARGA trim(" algo "); //elimina blancos iniciales y finales

Sobrecarga el operador '+' para concatenar cadenas

Conociendo el JDK

38

Introduccin
String z = "Este es" + " un letrero"; //

Es una fuente frecuente de basura.


"algo"+"de"+"basura"; procesar("algo".toUpperCase());

Comparaciones
De identidad: decide si dos valores son iguales. Estructural (mtodo) equals: decide si dos objetos son iguales con un criterio propio de la clase a la cual pertenece el objeto. Implementa la interfaz Comparable.
String z = "Este es" + " un letrero"; "Este es un letrero" == z ; //false !! "Este es un letrero".equals(z); //true "casa".compareTo("perro") ; // <0 "casa".compareTo("casa"); // 0 "casa".compareTo("balcon"); // > 0

El las comparaciones entre cadenas es bueno apoyarse en los literales para evitar "NullPointerException".
String x; ::: if(z.equals("casa")) { //peligroso !! } if("casa".equals(z)) { //recomendable }

El mtodo toString()
Muchos mtodos (de muchas clases) cuando reciben un Object como argumento, usan el servicio toString() para convertir el objeto en una cadena de caracteres. Es bueno que cada clase redefina el mtodo. Al hacerlo, es conveniente cuidarse de la produccin de basura. String s = "Esta " + "es " + "una " + "cadena";

java.lang.String

39

Introduccin
Persona p = new Persona(); System.out.println(p); System.out.println("persona = "+p);

FeeAssessment BUENA PRACTICA Cuando hay mltiples concatenaciones es mejor usar StringBuffer o StringBuilder que String para evitar producir basura.
StringBuffer sbf = new StringBuffer(); sbf.append("assessedAmount = "); sbf.append(assessedAmount); sbf.append(sep); sbf.append("paidAmount = "); sbf.append(paidAmount); sbf.append(sep); ::: return sbf.toString();

Manejo de Fechas
Clases java.util.Date, java.util.Calendar y java.text.SimpleDateFormat.

Date
Representa el tiempo como el nmero de milisegundos a partir del 1 de enero de 1970 Implementa la interfaz Comparable
Date d = new Date(); //Crea fecha en el instante actual. Date f; d.before(f); d.after(f); d.compareTo(f);

Para interactuar con bases de datos se usa la clase java.sql.Date que permite almacenar/extraer fechas com mayor precisin que java.util.Date

Calendar
Clase abstracta que permite manejar cmodamente (mediante constantes enteras) las nociones de dia, hora, mes, ao, etc .. que se encuentran dentro de una fecha. Las subclases de Calendar interpretan un Date de acuerdo con las reglas de un calendario especfico. El mtodo toString() 40

Introduccin El Jdk proporciona una subclase concreta: GregorianCalendar


Calendar cal = Calendar.getInstance(); //GregorianCalendar if(cal.get(Calendar.MONTH) == Calendar.NOVEMBER) { } if(cal.get(Calendar.DAY_OF_MONTH) <7) { } if(cal.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY) { }

Tiene operaciones "inteligentes" sobre fechas.

SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy"); Date d = sdf.parse("01-31-2007"); Calendar cal = Calendar.newInstance(); cal.setTime(d); cal.add(Calendar.MONTH,1); Date e = cal.getTime(); sdf.format(e);

// "02-28-2007"

sdf.format( cal.add(Calendar.DATE,1) .getTime()); // "03-01-2007"

Mtodos comunes a todos los objetos


Hay mtodos de la clase Object que definen (por defecto) ciertos comportamientos cruciales de los objetos y que son heredados por todas las clases en Java. A veces conviene redefinirlos pero siguiendo ciertos protocolos para mantener una coherencia global dentro de Java

toString()
Conviene redefinirlo para tener versiones "legibles" de los objetos. Util para depuracin. Se puede generar quasi automticamente. FeeAssessment

Calendar

41

Introduccin

equals()
Conviene redefinirlo cuando hay una nocin de igualdad lgica que va ms all de la simple identidad de campos.

Nodo

hashCode()
Calcula un entero que puede usarse como la "identificacin" del objeto. Contrato hashCode A- Siempre que se invoque sobre el mismo objeto, en la misma ejecucin de un programa, debe producir el mismo valor a menos que se haya cambiado uno de los atributos que intervienen en el clculo de equals(). El entero calculado no tiene que ser el mismo para diferentes ejecuciones del mismo programa. B- Si dos objetos son iguales, en el sentido equals(), el mtodo hashCode() debe producir el mismo valor para ambos. C- No se requiere que dos objetos no iguales, en el sentido equals(), tengan hashCode diferente. Sin embargo, producir hascodes distintos para objetos diferentes puede mejorar el desempeo de las estructuras basadas en tablas de hash. Receta

Ejemplo

Es obligatorio redefinirlo si se ha redefinido equals() No hacerlo es fuente de inconsistencias en el uso de las "colecciones" Java, pues fcilmente se viola la clusula B del "contrato".
Map map = new HashMap(); map.put(new Fee("Mora",234), "Carlos"); String s = (String)

equals()

42

Introduccin
map.get(new Fee("Mora",234)); // Retorna null si no se // redefine hashCode() !!

clone()
Mtodo protected de la clase Object que fabrica una copia (bit por bit) del objeto. Su ejecucin es lcita nicamente sobre clases que implementen la interfaz Cloneable La copia bit a bit puede ser peligrosa.

Casi siempre hay que redefinirlo: Por ser protected puede no ser accesible.
public class Puerta{ } public class Casa { Puerta p; void copiarPuerta(){ Puerta q = (Puerta)p.clone(); //error !! } }

public class Puerta implements Cloneable{ public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException e) { throw new Error("Ooops"); // No puede pasar } } }

Con frecuencia se requieren copias "estructurales" de los objetos.

hashCode()

43

Introduccin

Nodo

Colecciones
Infraestructura Java para manejar grupos de objetos: Arreglos Vectores, Listas, Conjuntos. Maps

Arreglos
Todos los elementos son del mismo tipo. Pueden almacenar valores primitivos u objetos.

Interface List
Ofrece servicios para manejar listas de objetos. Los objetos pueden ser de tipos diferentes. Las posiciones se cuentan a partir de cero. boolean add(Object o): agrega un objeto al final de la lista. Object get(int i): retorna el objeto en la posicin i de la lista. boolean add(int i, Object o): inserta un objeto en la posicin i de la lista, por el objeto o. Object set(int i, Object o): Cambia el objeto de la posicin i de la lista. boolean contains(Object o): retorna true si el objeto o est en la lista. int indexOf(Object o): retorna el ndice en donde se encuentra el objeto o, o -1 si no se encuentra. int size(): retorna el nmero de elementos en la lista. clone() 44

Introduccin boolean isEmpty(): retorna true si el nmero de elementos en la lista es 0. Object remove(Object o): elimina de la lista la primera aparicin del objeto o. Object remove(int i): elimina de la lista el objeto de la posicin i. Object [] toArray(): retorna un arreglo de objetos que contiene los mismos elementos de la lista. Iterator iterator(): retorna un iterador sobre los elementos de la lista. IMPLEMENTACIONES ArrayList: Se comporta como un arreglo de tamao variable. El acceso a cada elemento se hace en tiempo constante. LinkedList: Se comporta como una lista encadenada. El acceso a cada elemento es secuencial.
List lista = new ArrayList(); lista.add(new Puerta()); lista.add(new Casa()); Casa c = (Casa)lista.get(1);

Para almacenar valores de los tipos primitivos en una lista (u otras colecciones) se usan las clases "envolventes" o wrappers: Boolean Byte Character Integer Long Double Float
List lis = new LinkedList(); lis.add(new Integer(4)); //wrapper de enteros lis.add(new Boolean(true)); boolean b = ((Boolean)lis.get(1)).booleanValue();

Es muy frecuente que los elementos de una lista sean del mismo tipo
List lista = new LinkedList(); lista.add(new Integer(1));

Interface List

45

Introduccin
lista.add(new Integer(5)); lista.add(new Integer(3)); for(int i=0; i<lista.size(); i++) { Integer val = (Integer) lista.get(i); ::: }

for (Iterator iter = lista.iterator(); iter.hasNext();) { Integer val = (Integer) iter.next(); ::: }

Mecanismo cmodo para implementar mtodos que retornan varios valores. Ahorra la deficicin de clases pequeas que solamente tienen atributos.
public class Colecciones { :: public List multiResult (Map m) { int x; List y; :::: List result = new ArrayList(2); result.add(0,new Integer(x)); result.add(1,y); } } Colecciones c = new Colecciones(); Map map; ::: List calc = c.multiResult(map); int indice = ((Integer)calc.get(0)).intValue(); int lista = (List)calc.get(1); ::: public class IntLista{ public int indice; public List lista; }

Interface Set
Permite manejar grupos de objetos sin repeticiones: No puede contener dos elementos e1, e2 tales que e1.equals(e2) sea verdadero. Admite, a lo sumo, una aparicin de null. Los elementos pueden ser de tipos diferentes. Interface Set 46

Introduccin Representa la nocin matemtica de conjunto. Servicios boolean add(Object o): agrega el objeto o al conjunto, a menos que ya se encuentre en l. boolean contains(Object o): retorna true si el objeto se encuentra en el conjunto. boolean isEmpty(): retorna true si el conjunto est vaco. boolean remove(Object o): elimina al objeto o del conjunto, si est presente en l. int size(): retorna el nmero de elementos del conjunto. Iterator iterator(): retorna un iterador sobre los elementos del conjunto. Implementaciones HashSet: basada en tablas de hashing. Admite el elemento nulo. Garantiza tiempo constante para las operaciones bsicas. Muy sensible al "contrato de hashCode()"
Set conj = new HashSet(); conj.add(new Fee("Mora",234)); conj.contains(new Fee("Mora",234)); // Retorna null si no se // redefine hashCode() !!

TreeSet: Admite el elemento nulo. Mantiene los elementos ordenados ascendentemente segn el orden natural. No garantiza tiempo igual para las operaciones bsicas.
Set conj = new TreSet(); conj.add(new Fee("Mora",234)); conj.add(new Fee("Cheque devuelto", 500)); for (Iterator iter = conj.iterator(); iter.hasNext();) { Fee fee = (Fee) iter.next(); ::: }

Interface Map
Mantiene un conjunto de parejas <llave,valor > en donde tanto la llave como el valor son objetos. En general, null no puede ser una llave y en algunas implementaciones no puede ser un valor. Suele usarse como estructura de datos asociativa. Servicios

Interface Map

47

Introduccin Object put(Object llave, Object valor): asocia la llave con el valor en este map. Retorna el valor asociado. Object get(Object llave): retorna el valor asociado cn la llave, si est presente. Object remove(Object llave): elimina del map la asociacin para esta llave. Set keySet(): retorna el conjunto de las llaves del map. Set entrySet(): retorna el conjunto de asociaciones del map. Cada asociacin es de tipo Map.Entry boolean isEmpty(): retorna true si el map est vaco. int size(): retorna el nmero de asociaciones en el map. Implementaciones HashMap: basada en hash tables. Garantiza tiempo constante en las operaciones de acceso. Sensible al contrato de hashcode. TreeMap: mantiene las llaves ordenadas ascendentemente, segn el orden natural de la clase de las llaves. BUENA PRACTICA En el peor de los casos una coleccin es vaca. Jams nula.
List l; //peligroso List lista = new ArrayList();

Ordenamientos
Las colecciones tienen capacidades implcitas de ordenamiento, siempre y cuando los objetos que almacenan pertenezcan a clases que implementan la interfaz Comparable. Implementan el mtodo int compareTo(Object o); el cual define un orden natural para los objetos de la clase. El resultado de o1.compareTo(o2);se interpreta as: positivo significa o1 mayor-que o2 cero significa o1 igual-a o2 negativo significa o1 menor-que o2 FeeAssessment
FeeAssessment [] arrFass; ::: Arrays.sort(arrFass); //ordena ascendentemente

BUENA PRACTICA Ordenamientos 48

Introduccin Implementar la interface Comparable. La clase gana mucho, con poco esfuerzo. La mayora de las clases del JDK la implementan. SortWords
FeeAssessment [] arrFass; ::: Arrays.sort(arrFass); //ordena ascendentemente FeeAssessment fass; ::: int i = Arrays.binarySearch(arrFass, fass); // i > 0 => fass se encuentra en la posicion i // i <0 => i = -(punto de insercin) - 1

List fassList = new ArrayList(); //Lista de FeeAssessments ::: FeeAssessment fass = Collections.max(fassList);

Formateadores
Hay formateadores para nmeros y fechas. Su comportamiento depende del "Locale" escogido. El Locale por defecto es < en, US >.

DecimalFormat
Subclase de NumberFormat que formatea y lee (hace parsing) de nmeros decimales. Maneja formatos para: Enteros (123) Punto fijo (12.3) Notacin cientfica (1.23 E1) Porcentajes (12.3%) Dinero ($12.3)
String MONEY_FORMAT = "###,###,##0.00"; String PERCENTAGE_FORMAT = "###,###,##0.000000"; DecimalFormat mnf =

Formateadores

49

Introduccin
(DecimalFormat)NumberFormat.getInstance(); mnf.applyPattern(MONEY_FORMAT); mnf.format(16); // 16.00

DecimalFormat pctFm = (DecimalFormat)NumberFormat.getInstance(); pctFm.applyPattern(PERCENTAGE_FORMAT); pctFm.format(0.32); // 0.320000

SimpleDateFormat
Subclase de DateFormat que formatea y lee (hace parsing) de fechas y tiempo.
String DATE_FORMAT = "MM-dd-yyyy"; SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT); try { Date d = sdf.parse("11-08-2007"); ::: } catch(ParseException pe) { } String TIME_FORMAT = "HH:mm:ss.SSS"; sdf.applyPattern(TIME_FORMAT); sdf.format(new Date()); //10:28:35.045

System
No puede ser instanciada. Contiene campos estticos tiles: static InputStream in: Va estndar de entrada. static PrintStream out: Va estndar de salida. static PrintStream err: Flujo de errores. Mtodos static void exit(int status): Termina la ejecucin de la Mquina Virtual. static Properties getProperties(): Obtiene el conjunto vigente de propiedades del sistema. static String getProperty(String key): Obtiene el valor de una propiedad del sistema. DecimalFormat 50

Introduccin Se pueden agregar propiedades al conjunto de propiedades del sistema desde la lnea de comandos.
$ java -Dcasa=puerta basicos.SysProperties uno dos

System

51

Receta para hashCode()


12int result = 17 Para cada campo significativo "f" en el objeto (usado por equals() ) haga: a- Calcule el hashcode "c" dependiendo del tipo de "f": - booleano: c = ( f ? 0 : 1) - byte, char, short, int: c = (int) f - long: c = (int)(f ^ (f >>> 32)) - float: c = Float.floatToIntBits(f) - double: long ele = Double.doubleToLongBits(f); c = (int)(ele ^ (ele >>> 32)) - ref a objeto: c = f.hashCode() - arreglo: calcule para cada elemento su propio hashcode "c" y combnelo con los dems como en el paso "b-". b- Combine el hashcode "c" calculado en el paso "a-" as: result = 37 * result + c; 3- return result; 4- Ensaye a ver si objetos iguales producen hashCode() igual.

Receta para hashCode()

52

Entrada/Salida
Flujos
Un flujo (stream) es una secuencia de bytes. Archivos. Conexiones de red. Bloques de memoria. Los mecanismos de I/O de Java estn concebidos sobre la abstraccin de: Flujos de entrada: Objetos desde los cuales es posible leer secuencias de bytes (clase abstracta InputStream). Flujos de salida: Objetos a los cuales se puede enviar (escribir) secuencias de bytes (clase abstracta OutputStream). Los mtodos lanzan IOException.

java.io.InputStream
abstract int read(): Lee un byte y retorna lo ledo. Retorna -1 al final del flujo. int read(byte b[]): Lee sobre un arreglo de bytes y retorna el nmero de bytes ledos. Al final del flujo retorna -1. void close(): Cierra el flujo.

java.io.OutputStream
abstract void write(int b): escribe un byte en el flujo. void write(byte b[]): Escribe los bytes del arreglo b. void close(): Cierra el flujo. void flush(): Vaca el flujo y enva los bytes que puedan estar represados a su destino final. No es frecuente que el programador maneje datos a nivel de bytes: Las subclases de I/O(streams) proprocionan facilidades para manejar datos a ms alto nivel. Para manejar informacin en formato Unicode existe una jerarqua separada basada en las superclases abstractas:

Entrada/Salida

53

Introduccin java.io.Reader. java.io.Writer. Hay alrededor de 60 clases en la jerarqua de I/O de Java.

java.io.OutputStream

54

Introduccin

La jerarqua de clases de I/O en Java es intimidante!!

java.io.OutputStream

55

Introduccin

Decoracin de flujos.
Con FileInputStream y FileOutputStream se obtienen flujos asociados a archivos.
FileInputStream fin = new FileInputStream("empleados.dat"); File f = new File("empleados.dat"); FileInputStream fin = new FileInputStream(f); FileInputStream fin = new FileInputStream( new File("empleados.dat"));

byte b = fin.read(); //solo se leen bytes!!

Con DataInputStream y DataOutputStream se manejan los tipos bsicos de Java.

DataInputStream din =

::: ;

double s = din.readDouble();

Java separa dos responsabilidades: Tomar bytes de una fuente fsica. Ensamblar bytes para armar datos interesantes. El programador puede combinar estas capacidades para obtener flujos con el comportamiento deseado.
FileInputStream fin = new FileInputStream("empleados.dat"); DataInputStream din = new DataInputStream(fin); double s = din.readDouble();// lee un double // de un archivo DataInputStream din = new DataInputStream( new FileInputStream("empleados.dat");

Las subclases de FilterInputStream y FilterOutputStream se pueden filtrar para obtener flujos con capacidades muy flexibles. Lectura de tipos de datos primitivos de Java con buffer:
DataInputStream din =

Decoracin de flujos.

56

Introduccin
new DataInputStream( new BufferedInputStream( new FileInputStream("empleados.dat")));

Lectura con LookAhead y PushBack:


PushBackInputStream pbin = new PushBackInputStream( new BufferedInputStream( new FileInputStream("empleados.dat"))); int b = pbin.read(); if(b != '+') pbin.unread();

Manejo de archivos ZIP


La clase ZipInputStream permite crear un flujo a partir de un archivo .zip. ZipEntry getNextEntry(): Retorna la siguiente ZipEntry del flujo, o null si se llega al final. void closeEntry(): Cierra la ZipEntry actual del archivo y permite tomar la siguiente mediante getNextEntry.

//Ciclo tipico ZipInputStream zin = new ZipInputStream( new FileInputStream("archivo.zip")); ZipEntry entry; while((entry = zin.getNextEntry()) != null){ //Analizar entry; //Leer el contenido de zin; zin.closeEntry(); } zin.close();

//Mostrar en una TextArea el texto contenido en //un archivo que est dentro de un Zip. private TextArea fileText = new TextArea(); private String zipname; public void LoadZipFile(String name){ try{ ZipInputStream zin = new ZipInputStream( new FileInputStream(zipname)); ZipEntry entry; fileText.setText(""); while((entry = zin.getNextEntry()) != null){

Manejo de archivos ZIP

57

Introduccin
if(entry.getName().equals(name)) { BufferedReader in = new BufferedReader( new InputStreamReader(zin)); String s; while((s = in.readLine()) != null) fileText.append(s + "\n"); } zin.closeEntry(); } zin.close(); } catch(IOException ex){} }

Flujos de texto
Usan el Unicode. Son una jerarqua separada. Se construyen con las clases derivadas de Reader y Writer.

InputStreamReader: Transforma un flujo de bytes (que codifican cierto tipo de caracteres) en un flujo de caracteres.
InputStreamReader in = new InputStreamReader(System.in); InputStreamReader in = new InputStreamReader( new FileInputStream("enruso.txt"),"8859_5");

Es muy frecuente asociar un flujo de texto a un archivo:

FileWriter out = new FileWriter("salida.txt"); OutputStreamWriter out = new OutputStreamWriter( new FileOutputStream("salida.txt"));

Para conversiones (datos primitivos a texto) en salida se usa PrintWriter:


PrintWriter out = new PrintWriter( new FileWriter("salida.txt")); int i; boolean b;

Flujos de texto

58

Introduccin
out.println("i = "+i+" , b = "+b);

Leer valores de tipos bsicos, a partir de texto, es ms complicado: Se usa BufferedReader para tomar lneas de un flujo de caracteres
BufferedReader in = new BufferedReader( new FileReader("datos.txt")); String s; while((s = in.readLine()) != null) { //Hacer algo con s; double d = new Double(s).doubleValue(); }

Para analizar una cadena se usa la clase StringTokenizer Produce una enumeracin de tokens, dentro de una cadena, separados por caracteres predefinidos.
StringTokenizer st = new StringTokenizer("esto es una prueba"); while (st.hasMoreTokens()) { println(st.nextToken()); } // imprime esto es una prueba

Otro constructor: public StringTokenizer(String str,String delim)

Flujos de texto

59

Serializacin
Flujos de Objetos
Es sencillo guardar objetos en archivos, cuando son del mismo tamao. Los objetos en Java: Suelen ser de tamaos diferentes. Contienen referencias a otros objetos. Se comparten subestructuras. Es posible escribir algoritmos especficos para guardar(leer) un tipo de objetos especfico. En Java existe un mtodo general!!.
ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("empleados.dat")); Empleado luis = new Empleado(...); Empleado pedro = new Empleado(...); out.writeObject(luis); out.writeObject(pedro); //serializacion

ObjectInputStream in = new ObjectInputStream( new FileInputStream("empleados.dat")); //Se lee en el mismo orden en que se escribi. Empleado luis = (Empleado)in.readObject();//deserializar Empleado pedro = (Empleado)in.readObject();

Los objetos pueden ser guardados/ledos de un flujo de objetos si su clase implementa la interfaz Serializable .

class Empleado implements Serializable { :::: }

La serializacin se puede utilizar para clonar objetos sin mucho esfuerzo:


public class SerialCloneable implements Cloneable, Serializable{

Serializacin

60

Introduccin
public Object clone(){ try { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bout); out.writeObject(this); out.close(); ByteArrayInputStream bin = new ByteArrayInputStream( bout.toByteArray()); ObjectInputStream in = new ObjectInputStream(bin); Object ret = in.readObject(); in.close(); return ret; } catch(Exception e){ return null; } } } class Empleado extends SerialCloneable { ::::: } public class Test{ Empleado luis = new Empleado( :::: ); Empleado gemelo = (Empleado)luis.clone(); }

A veces puede ser til impedir la serializacin de algunos atributos Por razones de seguridad. No definen el estado del objeto sino que son una consecuencia de l.
public class Empleado implements Serializable{ Date nacimiento; String nombre; transient int edad; }

Flujos de bytes

Flujos de Objetos

61

Introduccin

Flujos de caracteres

Flujos de bytes

62

Introduccin

Flujos de caracteres

63

Archivos de Propiedades
Archivos de texto plano que contienen parejas (nombre,valor) y comentarios.
# Directorio de base base.dir=/usr/java/example #Fecha efectiva de procesamiento effective.date=10-24-2007

Son cmodos para pasar informacin de configuracin a las aplicaciones o, simplemente, para pasar datos.

Ejemplo

Archivos de Propiedades

64

El sistema de archivos
La clase java.io.File encapsula la funcionalidad requerida para interactuar con el sistema de archivos de la mquina. Es una representacin abstracta de un path dentro del sistema de archivos. Una vez creado es inmutable. Puede referirse a un archivo o a un directorio. El caracter separador de los componentes del path es accesible va: System.getProperty("file.separator") File.separator
File f = new File("texto.txt"); //no crea un archivo boolean b = f.createNewFile(); //crea un archivo //si no existe

String dirPath = "/home/rlopez/uis"; File f = new File(dirPath,"otro.txt"); if(f.exists()) { ::: }

File dir = new File("."); File f = new File(dir,"otro.txt"); if(f.exists()) { ::: }

Mtodos
boolean isAbsolute(): Decide si el path es absoluto. boolean isDirectory(): Decide si el path se refiere a un directorio. boolean isFile(): Decide si es un archivo. String [] list(): Calcula un arreglo con los nombres de todos los archivos y directorios contenidos en este directorio. boolean delete(): Elimina el archivo o directorio representado por este objeto. BUENA PRACTICA

El sistema de archivos

65

Introduccin Apoyarse en la clase System para evitar inconsistencias en I/O con respecto a las convenciones del sistema operacional
System.getProperty("line.separator"); System.getProperty("file.separator"); System.getProperty("path.separator");

Carga de Recursos
A travs del cargador de la clase se tiene acceso a recursos que estn en el classpath. Es una manera muy flexible de leer archivos: El acceso es independiente de la ubicacin absoluta del archivo dentro del sistema de archivos.

ResourceLoader
#!/bin/sh #----------------------# Archivo runLoader.sh #----------------------ROOT=".." BIN=${ROOT}/classes DATA=${ROOT}/data CP=${ROOT}:${BIN}

Mtodos

66

Introduccin
JAVA=${JAVA_HOME}/bin/java ${JAVA} -cp ${CP} io.ResourceLoader

Es particularmente til para empacar clases junto con recursos dentro de un archivo jar

Carga de Recursos

67

Swing
Java tambin es un lenguaje para programacin de Interfaces Grficas de Usuario (GUIs) a travs de un modelo "orientado por eventos". Los ambientes de desarrollo visuales ayudan a resolver los problemas bsicos de la parte grfica. El manejo de los eventos es responsabilidad del programador.

El desarrollo de interfaces grficas se basa en el uso de JFC: Java Foundation Classes: AWT : Abstract Window Toolkit (versiones 1.1 y posteriores). API 2D. Componentes Swing. API de accesibilidad.

Historia
Swing est construido sobre AWT que no fue diseado para uso interactivo serio: Java fue ms exitoso de lo que se pens originalmente. AWT no dispone de muchas facilidades estndar para GUI's: clipboard, impresin, navegacin con el teclado, mens pop-up, paneles con scroll. Modelo de eventos basado en herencia: pesado para escalar. Arquitectura de pares. Componentes nativos (del sistema bajo el cual corre Java), delegados por los componentes AWT para proporcionar la interfaz al usuario. Cada uno requiere de una ventana del sistema para desplegarse: muy exigente en recursos. Es muy difcil garantizar comportamiento uniforme entre plataformas diferentes. Las casas de software comenzaron a ofrecer productos para reemplazar a AWT. Eclipse ofrece SWT.

Componentes pesados vs. Componentes livianos


Componentes pesados:

Swing

68

Introduccin Estn asociados con un par nativo. Se despliegan en una ventana nativa y opaca. Componentes livianos: No tienen un par nativo. Se despliegan dentro de la ventana de su contenedor. Pueden tener fondo transparente. Pueden tener aspecto no rectangular. Todos los componentes del AWT eran pesados. Casi todos los componentes de Swing son livianos. Excepto los contenedores de alto nivel: frames, applets, dilogos. Hay componentes equivalentes a los del AWT (con extensiones). Hay componentes nuevos. Los nombres de las clases comienzan con J : JApplet, JButton, ...., JTabbedPane, JTable, etc.

SWING y AWT
Swing no reemplaza al AWT. Swing est construdo sobre el AWT.

Componentes pesados vs. Componentes livianos

69

Introduccin Un Applet

Manejo de Eventos
Los eventos se manejan con un modelo por delegacin. Los eventos son generados por fuentes de eventos. Uno o ms manejadores (oyentes, listeners) se pueden registrar para ser notificados de los eventos de cierto tipo provenientes de una fuente especfica.

Los manejadores de eventos pueden ser instancias de cualquier clase que implemente una interfaz apropiada (event listeners). En un programa que maneja eventos se ven, al menos, tres tipos de cdigo: Cdigo que declara que la clase implementa un oyente.
public class MiClase implements ActionListener { ::: }

Cdigo que registra una instancia de la clase oyente como manejador para los eventos de un componente.

unComponente.addActionListener(instanciaDeMiClase);

La implementacin de los mtodos de la interfaz oyente escogida.


public class MiClase implements ActionListener { ::: public void actionPerformed(ActionEvent e) { //Tratamiento del evento } :::

SWING y AWT

70

Introduccin
}

Ejemplo simple
Una fuente y un escucha.
public class Beeper implements ActionListener { Button boton; ::: //Se registra el beeper como escucha de ciertos eventos //del boton. boton.addActionListener(this); //Implementa el mtodo que atiende al evento. public void actionPerformed(ActionEvent e){ :::: } }

Un ejemplo ms complicado
En java es posible: Tener un oyente para cada fuente de eventos. Tener un oyente para todos los eventos de todas las fuentes. Tener ms de un oyente para un tipo de eventos de una nica fuente.

public class MultiListener implements ActionListener { void init() { //inicializacin ::: button1.addActionListener(this); button2.addActionListener(this); button2.addActionListener(new Oyente(bottomTextArea)); } public void actionPerformed(ActionEvent e) { topTextArea.append(e.getActionCommand() + newline); } } class Oyente implements ActionListener { ::: public void actionPerformed(ActionEvent e) { myTextArea.append(e.getActionCommand() + newline); } }

Manejo de Eventos

71

Introduccin

Interfaz de oyente de varios mtodos.


Un oyente para eventos de ratn debe implementar 5 mtodos:
public class MouseEventDemo implements MouseListener { void init() { //inicializacin ::: //Registro de atencin de eventos blankArea.addMouseListener(this); addMouseListener(this); } public void mousePressed(MouseEvent e) { saySomething("Mouse pressed; # of clicks: " + e.getClickCount(), e); } public void mouseReleased(MouseEvent e) { saySomething("Mouse released; # of clicks: " + e.getClickCount(), e); } public void mouseEntered(MouseEvent e) { saySomething("Mouse entered", e); } public void mouseExited(MouseEvent e) { saySomething("Mouse exited", e); } public void mouseClicked(MouseEvent e) { saySomething("Mouse clicked (# of clicks: " + e.getClickCount() + ")", e); } void saySomething(String eventDescription, MouseEvent e) { textArea.append(eventDescription + " detected on " + e.getComponent().getClass().getName() + "." + newline); } }

Los Eventos
Los eventos son objetos que contienen informacin acerca de la ocurrencia de hechos particulares durante la ejecucin de un programa. Requieren de soporte del sistema operacional para ser detectados (y comunicados) al programa. Hay un nmero finito de tipos de eventos previstos dentro de AWT.
ActionEvent AdjustmentEvent ComponentEvent ContainerEvent FocusEvent

Interfaz de oyente de varios mtodos.

72

Introduccin
ItemEvent KeyEvent MouseEvent MouseMotionEvent TextEvent WindowEvent

Para cada tipo de eventos hay una interfaz (event listener) que determina la signatura de los mtodos que pueden atender los eventos de ese tipo.
//ActionListener public void actionPerformed(ActionEvent e);

Las clases asociadas con los eventos proporcionan mtodos tiles para obtener informacin acerca del evento que representan. Clase ActionEvent: String getActionCommand(): Retorna una cadena asociada con la accin. int getModifiers(): Retorna un entero que indica las teclas modificadoras que pueden haber estado oprimidas cuando ocurri el evento. public static final SHIFT_MASK: Constante que seala el uso de la tecla shift.

Construccin de event listeners.


Son las clases que atendern los eventos que se producen en los componentes. Deben implementar la interfaz apropiada (.....Listener). Aunque solamente se quieran atender, explcitamente, unos pocos de los eventos que una fuente puede generar, hay que implementar todos los mtodos de la interfaz. Existen las clases adaptadoras para tratamiento de eventos, que tienen definiciones vacas de todos los mtodos de una interfaz.
/** * Clase que se apoya en un MouseAdapter */ public class MiClase extends MouseAdapter{ ::: unObjeto.addMouseListener(this); ::: public void mouseClicked(MouseEvent e) { //Implementacin del manejador. } }

Los Eventos

73

Introduccin

Clases internas
A veces no es posible derivar directamente de un adaptador pues la clase en cuestin ya deriva de otra clase. P.Ej: un applet. Se puede definir una clase interna que derive del adaptador.
/** * Uso de una clase interna. */ public class MiClase extends Applet{ ::: unObjeto.addMouseListener(new MiAdaptador()); ::: class MiAdaptador extends MouseAdapter{ public void mouseClicked(MouseEvent e) { //Implementacin del manejador. } } }

Por ser miembros de la clase que las contiene, tienen acceso a todos los miembros de la misma.

Clases internas annimas


Las clases internas que implementan manejadores de eventos tienen un uso muy controlado: Sus instancias son creadas por la clase que las contiene. Sus instancias son utilizadas por los componentes a quienes "atienden" para invocar los mtodos que implementan (mecanismo de callBack). Solamente la clase que las contiene necesita conocer su nombre => el nombre es superfluo. Existe una sintaxis para definir una clase interna annima en el sitio de creacin de una instancia.
/** * Uso de una clase interna annima. */ public class MiClase extends Applet{ ::: unObjeto.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { //Implementacin del manejador. } }); }

Clase del Applet

Archivo Applet.html

Clases internas

74

Introduccin
<HTML> <TITLE>Una Calculadora</TITLE> <BODY> <center> <H1>Una calculadora sencilla</h1> <APPLET CODE="swing.CalculatorApplet.class" WIDTH=200 HEIGHT=300> </APPLET> </center> </BODY> </HTML>

El patrn "Observer"
El manejo de eventos en Swing es una aplicacin del patrn "Observer".

Clases internas annimas

75

Java Beans y POJOs

Los Java Beans fueron los primeros "componentes" especificados por Sun. Originalmente pensados para ser manejados por ambientes grficos. Definen convenciones para manejo de propiedades. No deben confundirse con los Enterprise Java Beans (EJB). Son lo mismo que los POJO (Plain Old Java Objects) aunque deben cumplir con dos restricciones que stos no tienen: Deben ser serializables. Deben tener un constructor sin argumentos.

Propiedades
Son las caractersticas que definen el estado de un bean. Son accedidas mediante mtodos pblicos del bean llamados getters y setters. public void set<nombre-propiedad>(Tipo prop); public Tipo get<nombre-propiedad>();
/** * Clase con las propiedades * nacimiento y nombre. */ public class Persona { private Date nacimiento; private String nombre; public Date getNacimiento() { return nacimiento; } public void setNacimiento(Date nacimiento) { this.nacimiento = nacimiento; }

Java Beans y POJOs

76

Introduccin
public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } }

Una propiedad: Tiene tipo. Es "de lectura" si el bean tiene el correspondiente mtodo get. Es "de escritura" si el bean tiene el correspondiente mtodo set. No tiene que estar almacenada en un atributo del bean!!
public class Persona { private Date nacimiento; private String nombre; public Date getNacimiento() { return nacimiento; } public void setNacimiento(Date nacimiento) { this.nacimiento = nacimiento; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } /** * Propiedad "read only". */ public int getEdadEnAnhos() { Date hoy = new Date(); // Calcula la diferencia con // "nacimiento" } }

Propiedades Booleanas
Las propiedades booleanas admiten dos sintaxis para el mtodo "getter".
public class Persona { private char sexo; // 'M' o 'F' public boolean isHombre(){ return sexo == 'M';

Propiedades

77

Introduccin
} public setHombre(boolean b){ sexo = b ? 'M' : 'F'; } }

Propiedades indexadas
Representan colecciones de valores:
public <Tipo>[] get<Nombre>(); public void set<Nombre>(<Tipo>[] valor); public <Tipo> get<Nombre>(int i); public void set<Nombre>(int i, <Tipo> valor);

BUENA PRACTICA Respetar las convenciones de las propiedades de los Java Beans. Muchos "frameworks" modernos usan las propiedades de los beans: JSF, Spring, Java EE 5, Seam, etc. Es muy valiosos poder interactuar con esos "frameworks".

Manejo de Propiedades
Se pueden manejar directamente usando los getters y setters. El JDK incluye un API para manejarlas a travs de sus nombres. Como muchos APIs del JDK ... es incmodo de usar. Existen varios APIs de terceros.

Commons BeanUtils
Commons es un proyecto de Apache centrado en todos los aspectos de Componentes Reutilizables en Java. Tambin se conoce como Jakarta Commons. El programador Java que no usa Commons probablemente ha estado reinventando la rueda ... BeanUtils es un API para manejo de propiedades de beans
import org.apache.commons.beanutils.PropertyUtils; Person p = new Person(); p.setNombre("Rodrigo");

Propiedades Booleanas

78

Introduccin
try{ String nom = (String) PropertyUtils.getSimpleProperty(p,"nombre"); } catch ( ...) { //Hay que atrapar varias // excepciones .. }

public class Libro { private String titulo; public String getTitulo() { return titulo; } } Libro book = new Libro( ...); String titulo = (String) PropertyUtils. getSimpleProperty(book,"titulo"); String autor = (String) PropertyUtils. getNestedProperty(book,"autor.nombre");

Existen lenguajes para manejo de propiedades JSF EL (Expression Language). Seam EL. Extiende la nocin de propiedad. BUENA PRACTICA Antes de escribir "utilidades" para una aplicacin, echar una mirada a Apache Commons. "Reinventar la rueda" es muy ineficiente.

Reflexin en Java

Commons BeanUtils

79

Introduccin API estndar, diseado para analizar objetos y clases en tiempo de ejecucin. Las clases de este API representan mtodos, constructores, atributos y clases!!. java.lang.Class: Representa las clases de java.
try{ Class clazz = Class.forName("java.awt.Button"); } catch (ClassNotFoundException e){ ::: } import java.awt.Button; ::: Button b = new Button("Hola"); try{ Class laClase = b.getClass(); } catch (ClassNotFoundException e){ ::: }

java.lang.reflect.Method: Representa los mtodos de java.


import java.awt.Button; import java.lang.reflect.Method; ::: try { Button b = new Button("Hola"); Class laClase = b.getClass(); //Arma arreglo de parmetros formales Class parms [] = {String.class}; //Busca un mtodo Method metd = laClase.getMethod("setLabel",parms); //Invoca el mtodo Object args[] = {"Hello"}; metd.invoke(b,args); } catch ::: } catch ::: } catch ::: } catch ::: } (IllegalAccessException e){

(ClassNotFoundException e){

(NoSuchMethodException e){

(InvocationTargetException e){

java.lang.reflect.Field: Representa los atributos de una clase java.


:::

Reflexin en Java

80

Introduccin
try { Persona p = new Persona(); Class laClase = Persona.class; //Arma arreglo de parmetros formales Class parms [] = {String.class}; //Busca un atributo Field attr = laClase.getField("nacimiento"); //Obtiene el valor Object valAttr = attr.get(p); } catch ::: } catch ::: } catch ::: } catch ::: } catch ::: }

(NoSuchFieldException e){

(ClassNotFoundException e){

(NoSuchMethodException e){

(IllegalArgumentException e){

(IllegalAccessException e){

Reflexin en Java

81

Paralelismo
MultiTasking
Facilidad del sistema operacional que permite que haya ms de un programa ejecutando simultneamente.

Preemptive multitasking: El sistema administra los turnos entre las tareas. NonPreemptive multitasking: Los programas deben colaborar y ceder el turno.

MultiThreading
Un programa puede ejecutar mltiples tareas simultneamente. Cada tarea se denomina un thread (proceso liviano). Los programas que pueden correr ms de un thread se dicen multithreaded. Procesos vs Threads: Procesos: Manejan sus propias variables. Threads: Comparten datos. Es arriesgado. Es ms eficiente y ms flexible. Requiere sincronizacin si se comparten datos.

Threads en Java
Suelen crearse para ejecutar algoritmos independiente del "hilo" principal.
class MiThread extends Thread { ..... // atributos MiThread ( [parametros] ){ .... // constructor } void run() { .... // acciones para realizar // cuando se activa con start } // definicion de metodos auxiliares }

Paralelismo

82

Introduccin
:::: MiThread t1 = new MiThread (); MiThread t2 = new MiThread (); t1.start(); //ejecuta run() t2.start(); //ejecuta run()

Clase Thread: Constructor Thread (Runnable rn): Construye un thread a partir de un objeto Runnable. void run(): Si este thread fue construdo a partir de un objeto Runnable, se ejecuta el mtodo run() de ese objeto. Si no, se ejecuta este mtodo --que no hace nada--. void start(): Comienza la ejecucin de este thread. La JVM invoca el mtodo run() de este thread. static void sleep(long msecs): Suspende la ejecucin del thread --que se est ejecutando-- por un nmero de milisegundos. Implementa la interfaz Runnable que solamente contiene el mtodo run().
class MiRunnable [extends OtraClase] implements Runnable { MiRunnable ( [parametros] ){ } void run(){ } ::: } MiRunnable mr1 = new MiRunnable(..); MiRunnable mr2 = new MiRunnable(..); new Thread(mr1).start(); new Thread(mr2).start();

Es cmodo tener servicios de una clase que se puedan correr como threads separados o en el thread principal.
public class MiClase { public void unServicio(){ } public void threadService() { new Thread() { public void run() { unServicio(); } }.start();

Threads en Java

83

Introduccin
} } Miclase mc = new Miclase(); mc.unServicio(); //corre en el thread ppal. mc.threadService(); //corre en un nuevo thread.

Cuando se dispone de un nico procesador, correr mltiples threads no necesariamente mejora la eficiencia. Si alguno de los threads debe esperar (por causas naturales como operaciones de entrada/salida) usar mltiples threads puede reducir el tiempo de ejecucin. Los procesos batch suelen tener muchas operaciones de entrada/salida y suelen trabajar sobre datos independientes (son ideales para usar paralelismo).

Sincronizacin
Cuando mltiples threads acceden a un mismo dato puede ser conveniente "arbitrar"el acceso al dato.

Singleton BUENA PRACTICA Considere la posibilidad de usar paralelismo en sus procesos "batch". Pero sin reinventar la rueda. Java EE ofrece varias alternativas para poner en prctica el paralelismo.

Sincronizacin

84

Java 1.5
Lanzado en el 2004. Nombre clave Tiger Java Platform Standard Edition (J2SE) 5.0 Mejoras centradas en facilidades para el desarrollo.

AutoBoxing
Conversin automtica entre tipos primitivos y sus correspondientes "wrappers".
Integer i = new Integer(5); Map map = new HashMap(); //Antes de java 1.5 //map.put("result", // new Integer(i.intValue()+1)); map.put("result", i+1); //doble conversion

Los tipos primitivos no son reemplazados por los wrappers (ni lo contrario). Se pueden intercambiar y ocurren (automticamente) las conversiones necesarias: Como operandos. Como argumentos de mtodos. Como valores de retorno.

Enumeraciones
Mediante la palabra reservada enum se crea una nueva clase, que hereda de java.lang.Enum, y que contiene un conjunto de valores (tipados) con nombre. Se usan para reemplazar constantes enteras sobre las que no se poda hacer chequeo fuerte de tipos.
public class Geo { public static final int SUR = 1; public static final int NORTE = 2; public String showPuntoCardinal(int x){ String s = null; switch(x) { case SUR: s = "Sur"; break;

Java 1.5

85

Introduccin
case NORTE: s = "Norte"; break;

default: s = "Punto desconocido"; } return s; } } :::: new Geo().showPuntoCardinal(Geo.SUR); new Geo().showPuntoCardinal(32);//!!

//Archivo PuntoCardinal.java public enum PuntoCardinal { SUR,ORIENTE,NORTE,OCCIDENTE } public class Geo { public String showPuntoCardinal( PuntoCardinal x){ String s = null; switch(x) { case SUR: s = "Sur"; break; case NORTE: s = "Norte"; break; } return s; } } :::: new Geo().showPuntoCardinal(PuntoCardinal.SUR); new Geo().showPuntoCardinal(32);//Error!!

Ofrece una implementacin razonable de toString() y un valor entero asociado con cada nombre: ordinal().
public class Ordinales { public static void main(String [] args){ for (PuntoCardinal p: PuntoCardinal.values()) { System.out.println ( p + ", ordinal: ", p.ordinal()); } } } //Imprime SUR, ordinal: 0

Enumeraciones

86

Introduccin
ORIENTE, ordinal: 1 NORTE, ordinal: 2 OCCIDENTE, ordinal: 3

Genericidad
Permite crear clases, principalmente contenedoras, que pueden ser usadas con elementos de tipos diferentes. Se apoya en la nocin de tipos paramtricos.
//Antes de Java 1.5 class Contenedor{ private Object elemento; public Contenedor(Object o) { elemento = o; } public Object getElemento(){ return elemento; } } ::: Persona p = new Persona(); Contenedor con = new Contenedor(p); Persona q = (Persona)con.getElemento(); Carro c = (Carro)con.getElemento();//error en ejecucin!!

//Usando tipos parametricos en Java 1.5 class Contenedor <T> { private T elemento; public Contenedor(T o) { elemento = o; } public T getElemento(){ return elemento; } } ::: Contenedor <Persona> cper = new Contenedor(new Persona()); //warning (raw type) cper = new Contenedor <Persona>( new Persona()); Persona p = cper.getElemento(); //Sin casting cper = new Contenedor(new Carro()); //warning Contenedor <Carro> ccar = new Contenedor <Carro>(new Carro()); Carro c = ccar.getElemento();

Genericidad

87

Introduccin
ccar = new Contenedor (new Persona());//warning ccar = new Contenedor <Carro>( new Persona()); //error !!

El cdigo Java 1.4, compilado en Java 5, genera muchos warnings.


public class Tupla <A,B> { public final A first; public final B snd; public Tupla(A a, B b){ first = a; snd = b; } } ::: Tupla <int, Geo> tupla; // error. Los tipos primitivos // no se pueden usar como tipos // parametro. Tupla <Integer, Geo> tupla = new Tupla<Integer, Geo>(3, new Geo()); Tupla <int [], Geo> tupla = new Tupla(new int [] {1,2}, null); Tupla <int [], Geo> tupla = new Tupla <int [], Geo>( new int [] {1,2}, null);

Los tipos como parmtricos se pueden usar en cualquier sitio en donde sea lcito usar un tipo.
public class Geometria { ::: public Tupla <Angulo,Magnitud> calculoPolar(){ } ::: public void mostrarPolar(Tupla <Angulo,Magnitud> t) { } }

Es ms frecuente usar los tipos genricos del JDK que escribir tipos genricos. En las Colecciones del JDK con elementos del mismo tipo, es muy til la verificacin del tipo en tiempo de compilacin.
List <Persona> nomina = new ArrayList <Persona> ();

Genericidad

88

Introduccin
nomina.add(new Persona()); nomina.add(new Carro()); //error de tipo!! :::: for(Persona p: nomina){ p.subirSueldo(); }

El polimorfismo sigue funcionando.


class Hombre extends Persona { :: } class Mujer extends Persona { :: } List <Persona> alumnos = new ArrayList <Persona> (); alumnos.add(new Hombre()); alumnos.add(new Mujer()); Map <Hombre,Mujer> parejas = new HashMap <Hombre,Mujer> (); parejas.put(new Hombre(), new Mujer());

//Listas de elementos de "tipos distintos" List <Object> list = new ArrayList <Object> (); list.add(new Persona()); list.add(new Libro());

Interfaz Iterable
Se debe implementar para que los elementos de una clase puedan ser recorridos con la nueva sintaxis del for. Solamente contiene el mtodo iterator() que retorna un Iterator
public class Familia implements Iterable <Persona>{ String paisOrigen; String lenguaMaterna; private List <Persona> integrantes = new ArrayList <Persona> (); ::: public Iterator <Persona> iterator() { return integrantes.iterator(); } }

Interfaz Iterable

89

Introduccin
:::: Familia fam = new Familia(); :::: for(Persona p: fam) { p.subirSueldo(); }

Sorpresas
El sistema de tipos genricos de Java no es perfecto. Hay ms de una sorpresa escondida.

List <String> ls = new ArrayList <String> (); List <Object> lo = ls; //tipos incompatibles!! //Una lista de Object no es del mismo tipo //que una lista de String !! lo.add(new Object()); String s = ls.get(0); //Intenta asignar un Object //a un String

Comodines: Notacin para "tipo desconocido". Aparecen en situaciones como la de "escribir un mtodo que imprima todos los elementos de una Coleccin".

//Solucion en Java viejo void printColl(Collection c) { Iterator i = c.iterator(); for(int k=0; c.size(); k++) { System.out.println(i.next()); } } //Solucion ingenua usando genericidad void printCollIng(Collection <Object> c) { Iterator i = c.iterator(); for(Object e:c) { System.out.println(e); } }

El problema es que la segunda solucin es menos verstil que la primera. printColl admite cualquier Collection como argumento. printCollIng solamente admite valores de tipo Collection <Object> que, sabemos, no es supertipo de todas las colecciones. Cul es el supertipo de todas las colecciones?. Se escribe Collection <?>. Sorpresas 90

Introduccin Se lee "Coleccin de desconocido". Es un tipo comodn.

//Solucion generica void printCollGen(Collection <?> c) { Iterator i = c.iterator(); for(Object e:c) { System.out.println(e); } }

Otra sorpresa

Collection <?> c = new ArrayList <String>(); c.add(new Object());//error de compilacion

No se pueden agregar elementos a un Collection de desconocido!!! (excepto el valor null).

Referencias Generics in the Java Programming Language. Gilad Bracha, July 2004. Adding Wildcards to the Java Programming Language. Journal of Object Technology, Vol 3, No 11, 2004. Torgensen, Mads et al. BUENA PRACTICA El programador humilde usa la genericidad del JDK pero rara vez crea clases genricas.

El aporte ms valioso de la genericidad, en Java, es extender las capacidades de verificacin esttica de tipos. Disminuye las posibilidades de errores de ejecucin causados por incompatibilidades de tipo en los "castings".

Import esttico
Se usa para referirse a constantes estticas de una clase sin tener que mencionar el nombre de la clase o sin tener que heredar de ella.

import java.util.Calendar; import java.util.Date; import static java.util.Calendar.*;

Import esttico

91

Introduccin
public class StaticImport { void metodo(){ Calendar cal = Calendar.getInstance(); cal.setTime(new Date()); cal.add(Calendar.MONTH,1); //antes cal.add(MONTH,1); //en java 1.5 } }

Tambin sirve para importar las constantes de una enumeracin.

import static PuntoCardinal.*; public class C{ ::: PuntoCardinal p; if(p==NORTE) { } }

Nmero variable de argumentos


Facilidad inspirada en el lenguaje C en donde se conoce como varargs.
//Simulacion de numero variable de argumentos public class VarArgs { static void printArray(Object[] args) { for(Object o: args) System.out.print(o + " "); System.out.println(); } } :::: VarArgs.printArray( new Object [] { "uno", new Integer(2), new Persona() });

En Java 1.5 se introduce la notacin ... para indicar un nmero variable de argumentos. El compilador lo maneja internamente como un arreglo.

public class NewVarArgs { static void printArray(Object ... args) { for(Object o: args) System.out.print(o + " "); System.out.println(); } }

Nmero variable de argumentos

92

Introduccin
:::: NewVarArgs. printArray("uno", new Integer(2), 3); List <Object> list = new ArrayList <Object> (); list.add(1); list.add("dos"); NewVarArgs.printArray(list); //conversion automatica !!

El varargs tiene que ser el ltimo argumento de un mtodo. Puede ser "vaco". Puede especificar argumentos de cualquier tipo.
public class ArgOpcionales { static void f( int obligatorio, String ... opcionales){ System.out.println("Obligatorio = "+obligatorio); for (String s : opcionales) { System.out.print(s + " "); } System.out.println(); } public static void main(String ... args) { f(1); //opcionales vacio f(new Integer(2),"tres"); } }

Varargs introduce limitaciones en la sobrecarga (overloading) de mtodos


public class OverloadingVarargs{ static void f(Character ... args) { } static void f(Integer ... args){ } public static void main (String ... args) { f('a','b'); f(1,2); f();//ambiguo !! } }

Anotaciones
Mecanismo que permite agregar informacin (metadatos) al cdigo Java para ser utilizada despus. Anotaciones 93

Introduccin La informacin agregada no puede, en general, expresarse en Java mismo. Generacin de descriptores esperados por otras aplicaciones. Generacin automtica de nuevas clases. ... lo que el procesador de las anotaciones decida. Solamente hay tres anotaciones estndar en J2SE 5.0!!! @Override, @Deprecated, @SuppressWarning.

public class Casa{ @Override public String toStreng(){//error !! } }

Definicin de Anotaciones
La definicin de anotaciones es similar a la de una interfaz. Se utiliza el smbolo @ Requiere dos meta-anotaciones: @Target: define en dnde se puede aplicar la anotacin (PACKAGE, TYPE, FIELD, CONSTRUCTOR, METHOD, PARAMETER, LOCAL_VARIABLE). @Retention: define hasta cundo se mantiene la informacin de la anotacin: SOURCE: La anotacin es descartada por el compilador. CLASS: La anotacin est disponible en el byte code (archivo .class) pero puede ser descartada por la JVM. RUNTIME: La anotacin se conserva hasta tiempo de ejecucin y puede ser consultada mediante reflexin. Al compilar una anotacin se genera un archivo ".class". Ejemplo Suelen contener elementos: Anlogos a los mtodos de una interfaz. Sirven para pasar parmetros a la anotacin para cuando sea procesada.

Ejemplo
Una anotacin que sirve para hacer seguimiento a casos de uso en un proyecto:

Definicin de Anotaciones

94

Introduccin Los programadores anotan el mtodo o conjunto de mtodos que contribuyen a la implementacin de un caso de uso particular. El gerente de proyecto puede estimar el grado de avance del proyecto, contando el nmero de casos de uso implementados. Quienes hacen mantenimiento pueden encontrar fcilmente los casos de uso cuando se requieran cambios o correccin de errores. UseCase PasswordUtils Una anotacin, sin un procesador para ella, es poco ms que un comentario. El compilador solamente puede: Verificar los tipos de los parmetros que le son pasados Aplicar valores por defecto. La semntica de una anotacin la define el procesador diseado para ella. Un procesador sencillo Tipos vlidos para los elementos de las anotaciones: Tipos primitivos. String. Class. enum. Annotation. Arreglos de los anteriores.

Todos los elementos deben tener un valor (por defecto o especificado en el sitio de uso). Null no es un valor vlido para ningn elemento.
import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SimularNull{

Ejemplo

95

Introduccin
public int id() default -1; public String descrip() default ""; }

El 0,5% de los programadores escribe anotaciones para que el 99,5% las use. Cuando se va a usar una anotacin hay que leer el manual que la describe!!. En Java EE las anotaciones son cruciales. En general se procesan en el momento de despliegue de las aplicaciones.

Ejemplo

96

Log4J

API para manejar el rastro (log) de aplicaciones Java.


class Clase{ void prueba(int i){ //Nunca mas con log4j !! System.out.println( "paso por \"prueba\" con i = "+i); } }

Software libre del proyecto Apache. Es el estndar de facto para labores de logging. Incluido en todo tipo de herramientas, ambientes, servidores y frameworks del universo Java. Es rpido y flexible. Se instala muy fcilmente: viene en un ".jar" que debe estar al alcance del classpath. Se debe configurar (es muy flexible). Ha sido "portado" a C, C++, Qt/C, Eiffel, Lotus Script, Oracle PL/SQL, Perl, PHP, Phyton, Ruby y C#.

import org.apache.log4j.Logger; public class Hola{ static Logger logger = Logger.getLogger("milogger"); static public void main(String[] args) { logger.debug("Hola"); } } //falla con el mensaje log4j:WARN No appenders could be found for logger (milogger). log4j:WARN Please initialize the log4j system properly.

Log4J

97

Introduccin
import org.apache.log4j.Logger; import org.apache.log4j.BasicConfigurator; public class Hola{ static Logger logger = Logger.getLogger("milogger"); static public void main(String[] args) { BasicConfigurator.configure(); logger.debug("Hola"); } } //Muestra por la consola 10 [main] DEBUG milogger - Hola

Receta Global para usar Log4J


Configurarlo para la aplicacin especfica: Por programa (muy poco recomendable). Por archivos externos: de propiedades o scripts Xml. En cada clase en donde se requiera hacer log, obtener un logger.
static Logger logger = Logger.getLogger("edu.uis.Miclase"); static Logger logger = Logger.getLogger(Miclase.class);

Usar esa instancia del logger, invocando los mtodos de impresin: debug(), info(), warn(), error(), fatal(), log(). Esto producir el log por los dispositivos seleccionados segn la configuracin.

Arquitectura
Tiene tres componentes principales: Loggers. Appenders. Layouts. Interactan para hacer log de mensajes, dependiendo de su nivel, y controlan el formato y el destino de los mensajes.

Receta Global para usar Log4J

98

Introduccin

Jerarqua de Loggers
Los loggers son entidades con nombre. Importan las maysculas y minsculas. Forman una jerarqua

raiz com com.cincosoft com.cincosoft.uis milogger xml xml.java xml.java.Clase

El logger raz es especial: Siempre existe Su nivel no puede ser nulo. Solamente puede ser accedido mediante el mtodo esttico getRootLogger(). Los dems loggers: Se crean/acceden mediante el mtodo esttico getLogger. Un logger con un nombre dado se crea solo una vez (patrn singleton). Una manera natural de jerarquizar los loggers es darles el nombre de la clase en la cual son creados.

Niveles
Son la manera de clasificar la "importancia" de los mensajes producidos. De menos a ms importantes son: ALL DEBUG INFO WARN ERROR FATAL OFF Jerarqua de Loggers 99

Introduccin A un logger se le puede asignar un nivel. Un logger siempre tiene un nivel efectivo. El nivel effectivo de un logger L es igual al del primer nivel no nulo en la jerarqua de loggers, comenzando en L y ascendiendo hacia la raz. Nombre raiz x x.y x.y.z Nivel asignado DEBUG Nivel efectivo DEBUG DEBUG DEBUG DEBUG

Los mtodos de impresin de mensajes de los loggers estn asociados con un nivel implcito.
void void void void void void void void void void debug(Object msg); info(Object msg); warn(Object msg); error(Object msg); fatal(Object msg); debug(Object msg, Throwable th); info(Object msg, Throwable th); warn(Object msg, Throwable th); error(Object msg, Throwable th); fatal(Object msg, Throwable th);

Se comportan como un pedido de log hacia el logger. El logger filtra el pedido de acuerdo con su nivel efectivo. Un pedido de log de nivel p para un logger de nivel l pasa el filtro del logger si y solo si p >= l. En caso contrario el pedido es rechazado. Se puede asignar un umbral de filtro a toda la jerarqua de loggers, de manera que todo pedido por debajo del umbral sea rechazado, sin importar el logger que lo reciba ni su nivel efectivo. Por defecto, la jerarqua tiene el umbral ALL. Todos los mensajes se pueden inhibir asignando el umbral OFF.
Logger logger = ... ; void f(int i) { logger.debug("[f]: i = " + i);

logger.debug("{f}"); } void g(Date d) {

Niveles

100

Introduccin
logger.info("[g]: d = " + d);

Appenders
Definen el destino de los mensajes (impresora, consola, red, base de datos, un archivo, etc). Se pueden asociar uno o varios appenders a un logger. Aditividad de los appenders: Si un logger acepta un pedido, el pedido es transmitido a todos los appenders asociados con l y a todos los appenders que estn ms arriba en la jerarqua. La aditividad se puede inhibir, colocando el flag de aditividad del logger en false.

Combinando la aditividad y los nombres de las clases se pueden inhibir los mensajes de un paquete y sus "subpaquetes". ConsoleAppender: Enva el log a System.out/System.err. FileAppender: Enva el log a un archivo. Appenders 101

Introduccin RollingFileAppender: Enva el log a un archivo. Establece un lmite para el tamao del archivo. Cuando se alcanza el lmite, se crea un backup y se inicia uno nuevo. Establece un nmero mximo de backups. DailyRollingFileAppender: Enva el log a un archivo. Permite definir la periodicidad con la que se crea backup/renueva el archivo: Mensualmente. Semanalmente. Cada medio da. Diariamente. Cada hora Cada minuto SocketAppender. JMSAppender: Enva el log a un "topic" especificado con JMS. SMTPAppender.

Layouts
Permiten formatear los mensajes de log y agregarles informacin interesante. Se asocian con los Appenders PatternLayout Usa formatos de conversin similares a los del lenguaje C.
"%r[%t]%-5p%c - %m%n" ::: Logger log=Logger.getLogger("mi.logger"); log.info("Mensaje"); :::: 176 [main] INFO mi.logger - Mensaje

XMLLayout: Produce el log en un formato XML fijo. Hay un GUI, en Swing, para ver el contenido. HTMLLayout: Produce el log en un formato de tablas HTML.

Layouts

102

Introduccin

Configuracin
Permite definir todas las relaciones entre niveles, umbrales, loggers, appenders, layouts y formatos. Siempre hay que configurar (no hay configuracin "por defecto"). Por programa. Es engorrosa. Es la ms flexible (dinmica). Es muy raro usarla. Por archivos externos: propiedades, XML. Permite reconfigurar sin recompilar la aplicacin.

Configuracin en XML
El nombre, por defecto, del archivo es log4j.xml Basta con que se encuentre en un directorio que haga parte del classpath de la aplicacin. ... hay otras opciones.

ejemplo

BUENAS PRACTICAS En aplicaciones serias, olvidarse del System.out.println(..). Definir cuidadosamente para qu se va a usar cada nivel. De no hacerlo, solo se usa el nivel DEBUG y despus nadie cambia esa poltica. El nivel DEBUG tpicamente se habilita/deshabilita en aplicaciones en produccin. No subestimar el costo de construir los parmetros de los "pedidos", an si el umbral de la jerarqua es OFF.

logger.debug("casa = "+casa); if(logger.isDebugEnabled){ logger.debug("casa = "+casa); }

Evitar los pedidos dentro de loops muy activos. Si son indispensables, mantenerlos inhabilitados casi siempre.

Configuracin

103

Introduccin
boolean debug = logger.isDebugEnabled(); for( ; ; ) { if(debug){ logger.debug(:::); } }

En aplicaciones distribudas no hay quien supere al logger!! Una alternativa es la programacin orientada por Aspectos (AOP). JBoss, AspectJ, Spring.

Configuracin en XML

104

Vous aimerez peut-être aussi