« June 2004 »
SunMonTueWedThuFriSat
  
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
30
   
       
Hoy
XML

Unete al JUG de UPIICSA

Blog::Tags

Blog::Navigation

Blog::Editing

Bookmarks::Blogroll

Bookmarks::News

Blog::Referers

Las visitas de hoy a la página: 75

Site notes

This page validates as XHTML 1.0, and will look much better in a browser that supports web standards, but it is accessible to any browser or Internet device. It was created using techniques detailed at glish.com/css/.

Powered by Roller Weblogger.
Main | Next month (jul 2004) »
20040629 Tuesday June 29, 2004
Generics y Autoboxing

En un proyecto que recientemente he terminado, use JFreeChart y JfreeReport, ademas de estos frameworks, use JCommons.

Ya para terminar el proyecto, le agregue al proyecto (que es una aplicación Swing), un dialogo “Acerca de”.

JCommons, provee un dialogo de esta naturaleza, pense: “je je je, una tarea facil”.

Sucede que este dialogo lo use de esta manera:


  import org.jfree.ui.about.AboutFrame;
  import org.jfree.ui.about.ProjectInfo;


  ProjectInfo projectInfo = new ProjectInfo();
  projectInfo.setLogo(ResourceLoader.getImage("logoLeman.png"));
  projectInfo.setName("Leman");
  projectInfo.setVersion("0.9.2");
  projectInfo.setCopyright("Copyright (c) 1997-2004 Yum-Ká Software.");
  projectInfo.setInfo("Aplicación de un Sistema de Gestión de la Calidad");
  projectInfo.setLicenceName("GNU GPL");
  projectInfo.setLicenceText(ResourceLoader.getTextFile("licence-GPL.txt"));
  /**
   * Los siguiente métodos, reciben un objeto que 
   * implemente la interface List.
   */
  projectInfo.setContributors(null);
  projectInfo.setLibraries(null);
  AboutFrame aboutFrame = new AboutFrame("Acerca de", projectInfo);
  aboutFrame.show();

Hasta aquí todo sencillo y muy rápido.

Como verán, deje pendiente agregar al dialogo, la información referente a los desarrolladores y las librerias empleadas. Pues después de hacer la primera demo del proyecto, que me dicen. “Es necesario saber quienes participarón en el desarrollo del proyecto”. “Bueno”, pense, “Algo trivial”

Me di a la tarea de hacer lo que me habian pedido. Entonces empezaron unos cuantos detalles. Antes de seguir, deben saber, que estaba usando el J2SE SDK 1.4.2_04.

Me pidieron varios cambios, ya saben, cambios no documentados, asi que empece con aquellos que eran prioritarios. Deje al final, lo del dialogo “Acerca de”

Cuando llegue a esa parte, intente atacar el problema asi:

  ArrayList developers = new ArrayList();
  ArrayList libraries = new ArrayList();
  developers.add("Desarrollador 1");
  developers.add("Desarrollador 2");
  developers.add("Desarrollador n...");
  libraries.add("JFreeReport");
  libraries.add("JFreeChart");
  libraries.add("JCommons");
  projectInfo.setContributors(developers);
  projectInfo.setLibraries(libraries);

No lei la documentación de JCommons, asi que me lleve una grata sorpresa al ejecutar mi aplicación y al tratar de mostrar mi “Acerca de”....

java.lang.ClassCastException

“mmm, algo anda mal, ¿Que sera?”. Me tome unos minutos para checar el codigo fuente de JCommons, y descubri mi error. Resulta que el objeto contenedor que almacena los “contributors” y las “libraries”, debe almacenar objetos Contributor y Library, respectivamente.

La JVM, me escupia este error, al tratar de convertir el objeto almacenado en el ArrayList, en un Contributor, en el ArrayList, yo estaba guardando un String.

El error anterior no me hubiera pasado en tiempo de ejecución en el nuevo y flamante J2SE SDK 1.5.0-beta2-b51, lo hubiera tenido en tiempo de compilación. Esto debido a la caracteristica de Generics, disponible a partir de esta versión. Pero bueno, antes de abordar Generics y Autoboxing, les comento como resolvi mi problema y me cubri de gloria al entregar el proyecto. :P


  ArrayList contributors = new ArrayList();
  ArrayList libraries = new ArrayList();
  Contributor c;
  Library l;
  c = new Contributor("Desarrollador 1", "dev01@server.com");
  contributors.add(c);
  c = new Contributor("Desarrollador 2", "dev02@server.com");
  contributors.add(c);
  c = new Contributor("Desarrollador n", "devnn@server.com");
  contributors.add(c);
  l = new Library("JFreeChart", "0.9.18", "license", "info");
  libraries.add(l);
  l = new Library("JFreeReport", "0.8.4.10", "license", "info");
  libraries.add(l);
  projectInfo.setContributors(contributors);
  projectInfo.setLibraries(libraries);

Ahora si, pues resulta que los tipos genericos era algo que a Java la hacia mucha falta, hace tiempo C# implementa esta funconalidad, cuando lei la especificación me agrado mucho, casi me paso al lado obscuro de la fuerza. :)

En fin, explico brevemente:

El ArrayList, puede almacenar cualquier tipo de objeto Java, para ser exactos, cualquier objeto que descienda de java.lang.Object. También puede almacenar tipos de datos primitivos, gracias al Autoboxing. El Autoboxing es el proceso de convertir tipos primitivos a objetos Java y viceversa, esto de manera automatica.Esta conversión tiene la pega en el performance de la aplicación. No es recomendable utilizar en exceso el Autoboxing.

Sin generics, por ejemplo si deseamos crear una estructura que almacene objetos de una sola clase, tenemos de dos sopas:

  1. Crear una clase contenedor, que solo admita el tipo de objeto que nosotros especifiquemos.

  2. Dejar que el desarrollador no meta la pata y solo almacene en algún contenedor Java(ArrayList, y compañia) los objetos de la clase especificada.

Si consideramos la primera opción, esto supone trabajo extra al desarrollador, ya que necesita diseñar e implementar esta clase, un ejemplo hipotetico seria:

Supongamos que deseamos almacenar en un ArrayList objetos de esta clase.

class MiObjeto {
  private String nombre;
  public MiObjeto(String nombre) {
    this.nombre = nombre;
  }
  public String toString() {
    return this.nombre;
  }

}

Ahora, creamos una clase se solo admita almacenar en ella objetos de tipo MiObjeto. La implementación de una clase con la funcionalidad de un ArrayList por ejemplo, requiere mucho trabajo, y eso solo para que pueda almacenar unicamente objetos MiObjeto. Si necesitamos almacenar otro tipo de objetos, hay que crear esa clase. Demasiado trabajo, para algo tan simple.

Ya vimos que si usamos el segundo enfoque, pues estamos propensos a muchos errores, y lo peor es que la mayoria de ellos solo se detectan en tiempo de ejecución.

Con generics, esto se facilita mucho, si tenemos la necesidad de una estructura que solo admita objetos de tipo MiObjeto, la implementación es muy sencilla y limpia:

public class Demo {
  public static void main(String[] args) {
    // podemos tener Collecciones de objetos, de tipos seguros
    Collection<MiObjeto> nombres = new ArrayList<MiObjeto>();
    nombres.add(new MiObjeto("domix"));
    nombres.add(new MiObjeto("mirix"));
    nombres.add(new MiObjeto("lulix"));
    nombres.add(new MiObjeto("jessix"));
    nombres.add(new MiObjeto("javix"));
    // esto es fabuloso¡¡
    for(MiObjeto nombre : nombres) {
      System.out.println("nombre = " + nombre);
    }
  }
}

La salida del programa es algo parecido a esto:

E:\pruebasSDK1.5>ant
Buildfile: build.xml
compilar:
    [javac] Compiling 1 source file to E:\pruebasSDK1.5\classes
probar:
     [java] nombre = domix
     [java] nombre = mirix
     [java] nombre = lulix
     [java] nombre = jessix
     [java] nombre = javix
BUILD SUCCESSFUL
Total time: 3 seconds


Si el desarrollador es muy despistado y codificara algo mal, como esto:

public class Demo {
  public static void main(String[] args) {
    // podemos tener Collecciones de objetos, de tipos seguros
    Collection<MiObjeto> nombres = new ArrayList<MiObjeto>();
    nombres.add(new MiObjeto("domix"));
    nombres.add(new MiObjeto("mirix"));
    nombres.add(new MiObjeto("lulix"));
    nombres.add(new MiObjeto("jessix"));
    nombres.add(new MiObjeto("javix"));
    nombres.add("burrix");
    // esto es fabuloso¡¡
    for(MiObjeto nombre : nombres) {
      System.out.println("nombre = " + nombre);
    }
  }
}

El compilador nos “avisa”, del despiste y no permite compilar

E:\pruebasSDK1.5>ant
Buildfile: build.xml
compilar:
    [javac] Compiling 1 source file to E:\pruebasSDK1.5\classes
    [javac] E:\pruebasSDK1.5\src\Demo.java:23: add(MiObjeto) in java.util.Collection<MiObjeto> cannot be applied to (java.lang.String)
    [javac]     nombres.add("burrix");
    [javac]            ^
    [javac] 1 error
BUILD FAILED
E:\pruebasSDK1.5\build.xml:8: Compile failed; see the compiler error output for
details.
Total time: 3 seconds


Muy cojonudo, ¿no?.


Otra caracteristica muy fregona de este nuevo SDK, es la nueva sintaxis del for. Chequen:

  for(MiObjeto nombre : nombres) {
    System.out.println("nombre = " + nombre);
  }

Para recorrer el ArrayList, ya no es necesario obtener un Iterator y movernos a travez de el. Ahora con la sintaxis de arriba podemos recorrer el ArrayList, de una manera muy sencilla. Aunque podemos seguirlo haciendo a la manera antigua.

Ahora me surgio una inquietud, ¿Que pasa si decompilamos el byte-code de la clase?.

Increiblemente obtenemos el suguiente código:

// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
import java.io.PrintStream;
import java.util.*;
public class Demo
{
    public Demo()
    {
    }
    public static void main(String args[])
    {
        ArrayList arraylist = new ArrayList();
        arraylist.add(new MiObjeto("domix"));
        arraylist.add(new MiObjeto("mirix"));
        arraylist.add(new MiObjeto("lulix"));
        arraylist.add(new MiObjeto("jessix"));
        arraylist.add(new MiObjeto("javix"));
        MiObjeto miobjeto;
        for(Iterator iterator = arraylist.iterator(); 
            iterator.hasNext(); 
            System.out.println((new StringBuffer()).append("nombre = ").append(miobjeto).toString()))
            miobjeto = (MiObjeto)iterator.next();
    }
}

Como ven el compilador si genera el código para obtener el Iterator y hacer el recorrido como ha sido siempre. Genial. :)


Hasta la otra.

domix

20040601 Tuesday June 01, 2004
Buenas experiencias

Bueno, pues resulta que ultimamente, he tenido buenos momentos, algunos de ellos (la mayoria) con mis amigos, nos hemos tomado unas fotos.

Aqui estamos de izquierda a derecha, Alexandra, Denyce, Humberto y yo.

Alexandra y Denyce, estuvierón como edecanes en la conferencia de hace dos semanas, Humberto me ayudo también.

De izquierda a derecha: Luis Mani, yo, Alexandra (otra), Marcos y Alejandro

Mani y Alejandro me ayudarón mucho también en la conferencia.

Aqui los cuatro fantásticos de las duelas, je je je

Vaya que me veo bajito, ellos son muy altos, yo mido 1.78 mts.

Me he divertido mucho con ellos, hemos aprendido juntos, el año que compartimos ha sido uno de los mejores que he tenido en la escuela.

Por cierto las fotos las tomamos en la escuela, en las dos últimas estamos a un costado de los jardines de la biblioteca, es el edificio que se ve al fondo.

Y hablando de otras cosas, el JUG va bien, he conocido algunos miembros más, ya somos 74.  Hay interes pero parece que no tiempo, justo esta semana empezamos examenes finales, asi que no espero mucha participación.

Fin de semestre, fin de clases....

Copyright (C) 2003-2004, La zona muerta