Buscar
Social
Ofertas laborales ES
martes
feb192002

Un escritorio escrito en Java?

Cuando encontre esta herramienta hace una semana la descarte por estrafalaria, pero viendo el revuelo que ha creado en otros sitios me decidi a echarle un vistazo, y tengo que decir que el resultado, robando las palabras de Jesulín, es in presionante.


Por supuesto se trata de una herramienta limitada, esta por la versión 0.16, pero no deja de mostrar lo interesante de su propuesta: un escritorio para ordenador escrito 100% en Java.


El día que tengamos un SO 100% en Java solvente ya nadie nos sacará de ahí ;-).
lunes
feb182002

Ideas para mejorar el rendimiento

Echidna en es una especie de servidor que puede hacer que nuestras aplicaciones java arranquen mucho más rápido.


Haciendo que nuestras aplicaciones Java corran como hilos de una misma JVM en lugar de cargar una nueva maquina virtual para cada aplicación puede reportar interesantes mejoras en el rendimiento, ya sea en la carga de la aplicación o en la memoria necesaria.
sábado
feb162002

Nueva versión del servidor de aplicaciones Orion

Acaba de salir la versión 1.5.4 del servidor de aplicaciones Orion, servidor que como muchos sabréis se encuentra introducido mediante una licencia especial en el servidor de aplicaciones de Oracle (OAS).

Esta nueva versión introduce importantes novedades como interfaces locales ( fundamental ), relaciones M:N, borrados en cascada, claves primarias automáticas y más.

Podéis bajaroslo de aquí
sábado
feb162002

Diario de un principiante (Capítulo 4)


Métodos y Clases en Java: Parte II


Continuamos en este artículo la discusión sobre aspectos más avanzados de la POO en Java.

Introducción: Polimorfismo en Java


Esta palabra que significa "muchas formas", es una característica del lenguaje Java que permite a una interface
ser usada por una clase general de acciones. La acción concreta a llevar a cabo se determina por la naturaleza
específica de la situación.

En términos más generales, el concepto de polimorfismo a menudo se expresa por la frase "una interfaz, múltiples
métodos". Esto significa que es posible diseñar una interfaz genérica para un grupo de actividades relacionadas.
Es evidente que esta forma de trabajar ayuda a reducir la complejidad del diseño, pues permite usar una misma
interfaz para especificar un conjunto de acciones similares. Será el compilador el que tendrá que seleccionar
la acción concreta (esto es, el método) para aplicar en cada situación. Como programadores, nosotros solo
tenemos que conocer la interfaz general. En el siguiente apartado se relata un caso práctico que ayudará a entender los
beneficios del polimorfismo.


Sobrecarga de métodos


Otra de las ventajas de este lenguaje de programación es que nos permite definir dos o más métodos
dentro de la misma clase con el mismo nombre, siempre que la declaración de sus parámetros sea diferente.
En este caso se dice que el método está sobrecargado y el proceso de definir un método así se
conoce como sobrecarga del método. La sobrecarga de métodos es una de las maneras en que Java implementa el polimorfismo.

Cuando se llama a un método sobrecargado, el compilador actúa justo sobre la versión cuyo tipo de parámetros coincida
con los de la llamada. Así, se podría definir la siguiente clase "SumaGenerica" que aglutinara las sumas de todos los tipos primitivos:


class SumaGenerica {
int suma (int a, int b) {
return a+b;
}

double suma (double a, double b) {
return a+b;
}
...
}

NOTA: Realmente no sería necesario definir el método suma() para todos los tipos de datos, pues aquí también interviene
el casting implícito que hace Java. Por ejemplo, una suma de float, llamaría automáticamente al método que devuelve double siempre y cuando
no esté definido el método que devuelve float, claro está.


No existe una regla exacta par saber si un método se debe sobrecargar o no. Realmente, la idea es aprovechar las ventajas que
ofrece esta forma de polimorfismo, así que lo normal es sobrecargar aquellos métodos que estén intrínsicamente relacionados, como es el
caso del ejemplo anterior pero no nos debemos confundir. Por ejemplo, el método sqrt(), aunque se llama igual, calcula
de forma totalmente diferente la raiz cuadrada de un número entero que la de uno en punto flotante. Aquí, aunque aplicaramos
sobrecarga al método, realmente no estaríamos respetando el propósito para el que se creó el polimorfismo.

Sobrecarga de Constructores


Es aquí donde realmente se aprecia los beneficios del polimorfismo. Como sabemos, el constructor de una clase es el que inicializa los valores que el programador crea conveniente cuando
ésta se instancia. Pues bien, sobrecargando el constructor conseguimos dotar a la clase de flexibilidad. Por ejemplo, como mínimo se debería tener en cuenta
que podría no pasarsele parámetros al constructor, cuando éste lo espera, debido a un fallo en alguna otra parte de la aplicación
(me refiero a cualquier otra clase que llame a ésta).
Es por ello que siempre es recomendable definir al menos dos constructores: el específico de la aplicación que estemos diseñando y el "estándar". El siguiente ejemplo te lo va a dejar mucho más claro:

class Box {
double width;
double height;
double depth;

//El siguiente es el constructor específico
Box(double w, double h, double d) {
width = w; height = h; depth = d;
}

//pero podría ser que no le llegarán parámetros
// por fallar la otra clase (método) que lo invoque
Box () {
width = height = depth = -1 //-1 indica volumen no existente
}
//e incluso podemos pensar que se quiere construir un cubo,
//entonces, por qué introducir 3 valores? ;)
Box (double valor) {
width = height = depth = valor;
}

double volume() {
return width * height * depth;
}

Como ves, de cara a flexibilizar una clase es fundamental el polimorfismo a la hora de implementar los constructores.

Objetos como parámetros


A parte de usar los tipos primitivos como parámetros, en Java es perfectamente posible pasarle a un método un objeto como parámetro.

class Comparar {
int a, b;

Comparar (int i, int j) {
a = i;
b = j;
}

boolean equals (Comparar c) {
if (c.a == a && c.b == b) return true;
else return false;
}
}

Como se puede apreciar, el método equals() de Comparar comprueba si dos objetos son idénticos
. Esto es, compara el objeto que invoca el método con el que se le pasa al método como argumento.
Acabo de liarte? ;), pues fíjate en el siguiente trozo de código que se explica mucho mejor.

class PasaObjeto {
public static void main(string args[]) {
Comparar objeto1 = new Test(2,3);
Comparar objeto2 = new Test(2,3);
System.out.println(objeto1.equals(objeto2));
}
}

Como ves, objeto1 es el que invoca el método y objeto2 es
el que se pasa como argumento al método equals() de objeto1.


Observa también que el parámetro c en equals() especifica Comparar como tipo.
Aunque Comparar es un tipo de clase creado por el programa, éste se usa de la misma manera
que los tipos primitivos que Java nos proporciona.

Una mirada más cercana al paso de argumentos


Como sabemos, existen dos formas de pasar un argumento a una rutina:

  • Por valor: El método copia el valor de un argumento en el parámetro formal de la rutina.
  • Por referencia: Se pasa al parámetro de la rutina la referencia al argumento (no su valor).

En el primer caso, al ser solo una copia, cualquier modificación dentro de la rutina de ese valor no tendrá
efecto una vez fuera de éste mientras que si es por referencia, sí persistirá la modificación
hecha una vez salgamos de la rutina.


Pues bien, cuando en Java se pasan argumentos de tipo simple, estos siempre se hacen por valor. Entonces, cómo puedo pasar un
parámetro por referencia para modificarlo?. Pues muy fácil, pasando el objeto. Esto ocurre porque cuando tu creas una variable de un tipo de clase,
tu solo creas una referencia al objeto. Así, cuando pasas esta referencia a un método, el parámetro
que recibe éste se refiere al mismo objeto que el referido por el argumento. Por tanto, los cambios que se hagan en la referencia de
la rutina afectarán también al objeto pasado como argumento.

El Operador static


Hay veces que se desea querer definir una clase miembro para ser usada
independientemente de cualquier objeto de esa clase. Normalmente a una clase miembro se accede
solo si hemos instanciado un objeto de dicha clase. No obstante, es posible crear un miembro
que pueda ser usado por si mismo, sin necesidad de referenciar a una instancia específica. Para crear tales
tipos de miembros se emplea el operador static.

Cuando un miembro se declara con esta palabra reservada, se puede acceder a él
antes de que cualquier objeto de su clase sea creado, y sin referenciar a ningún objeto. Puedes declarar tanto los métodos
como las variables como static. El ejemplo más claro de un miembro static es el main(). Se declara de esta manera
porque se debe llamar antes de que cualquier objeto sea declarado.

Las variables static


Las variables de instancia declaradas como static (también llamadas "de clase") son, esencialmente, variables globales. Cuando creamos objetos específicos
de esa clase no se hace ninguna copia de las variables static. Lo que ocurre es que todas las instancias de esa clase
comparten la misma variable static. Estas variables mayormente tienen sentido cuando varias instancias de la misma clase necesitan
llevar el control o estado del valor de un dato. También se podrían utilizar para definir constantes, pero cuando menos es aconsejable
que también se emplee el operador que se explica en la siguiente sección.

Para llamar a este tipo de variables se suele utilizar el nombre de la clase
(no es imprescindible, pues se puede utilizar también el nombre de cualquier objeto), porque de esta forma queda más claro, seguida de un "." y
la variable, por ejemplo, Estatica.b

Las variables miembro static se crean en el momento en que pueden ser necesarias: cuando se va
a crear el primer objeto de la clase, en cuanto se llama a un método static o en cuanto se utiliza una variable static de dicha clase. Lo
importante es que las variables miembro static se inicializan siempre antes que cualquier objeto de la clase.

Los métodos static


También llamados "de clase", pueden recibir objetos de su clase como argumentos explícitos, pero no tienen argumento implícito ni
pueden utilizar la referencia this. Para llamar a estos métodos se suele emplear el nombre de la clase, en vez del nombre de un objeto de la clase. Los métodos y variables de clase
son lo más parecido que Java tiene a las funciones y variables globales de C/C++.

Las restricciones que tiene un método static son:


  1. Solo pueden llamar otro método static
  2. Solo deben acceder a datos static
  3. No se pueden referir a this o super de ninguna manera

Si se necesita hacer algún tipo de computación para inicializar las variables static, se puede declarar también un bloque static el cual se ejecutará
solo una vez, cuando se carga.

class Estatica {
static int a = 3;
static int b;

static void show(int x) {
System.out.println("x = " + x);
System.out.println("a = " + a);
System.out.println("b = " + b);
}

static {
System.out.println("Bloque estático inicializado");
b = a * 4; //vemos que, aunque declarada como static
//b se inicializa en tiempo de ejecución
}

public static void main(String args[]) {
show(15);
}
}

Tan pronto como Estatica se carga, todas las sentencias se ejecutan.
Primero, a se inicializa a 3, luego se ejecuta el bloque estático y, por último,
b se inicializa al valor asignado.

El operador final


Una variable que se declara como final, se previene que su contenido sea modificado. Esto significa
que debes inicializar una variable como final cuando la declaras. No obstante, Java permite separar la
definición de la inicialización. Esta última se puede hacer más tarde, en tiempo de ejecución,
llamando a métodos o en función de otros datos. La variable final así definida es constante pero no tiene
porqué tener el mismo valor en todas las ejecuciones del programa, pues depende de cómo haya sido inicializada.
Esto es lo más parecido a las constantes de otros lenguajes de programación. Por ejemplo:

final float PI = 3.1416;//Según la convención de código las variables "constantes"
//se ponen en mayúsculas.
//Observa que ahora podrás usar esta variable sin miedo a
//ser modificada, esto es, tienes una constante.

Aunque básicamente este operador se emplea para crear constantes en Java, también podemos definir una clase
o un método como final. En el primer caso, no puede tener clases derivadas. Esto se hace por motivos de seguridad y de eficiencia, porque cuando el compilador
sabe que los métodos no van a ser redefinidos puede hacer optimizaciones adicionales.

En el segundo, un método declarado como final no puede ser redefinido por una clase que derive
de su propia clase.

En el próximo capítulo acabaremos de ver otros conceptos de la POO y algunos aspectos del uso de clases con los operadores explicados. También haremos un
repaso de lo que son las clases internas y las clases anidadas.















Leo Suarez es un Ingeniero Superior de Telecomunicaciones por la
Universidad de Las Palmas de Gran Canaria con todas sus letras, que no
son pocas, y trabaja como tal en Santa Cruz de Tenerife.
Cuando no
está saltando de isla en isla o escribiendo para javaHispano aprovecha
para disfrutar con la novia y los amigos del estupendo clima de las islas afortunadas.

Para cualquier duda o tirón de orejas, e-mail a:
leo_ARROBA_javahispano.com




sábado
feb162002

XML desde java hecho fýcil: JDOM

JAVA+XML = JDOM (Parte 1)



Introducción




JDOM es un API para leer, crear y manipular documentos XML de una manera sencilla y muy intuitiva para cualquier programador en Java, en contra de otras APIs tales como DOM y SAX, las cuales se idearon sin pensar en ningún lenguaje en concreto, de ahí que resulte un poco incomodo su utilización.



En este articulo exploraremos un poco el API, crearemos una pequeña aplicación que lea un documento XML y sacaremos de él aquellas partes que nos interese. Para abrir boca, imagínate este trozo de XML:




...
<site>javahispano</site>
...



Se imagina acceder al texto del elemento site de esta manera:




String nombre = site.getText();



¿Te gusta? Esto es JDOM.




Donde se encuentra JDOM




Para comenzar haremos una visión de pájaro para ver donde encajamos JDOM en un pequeño esquema.






Antes de seguir adelante permitirme una aclaración: DOM y SAX son dos especificaciones que como tal no podemos trabajar con ellas, pero si con las implementaciones de dichas especificaciones, es decir, los parsers: Xerces, XML4j, Crimson, Oracle's parsers,...



Pues bien un ultimo apunte, la API JDOM no es un parser, de echo, usa un parser para su trabajo, JDOM "solo" nos aporta una capa de abstracción en el tratado de documentos XML facilitándonos bastante la tarea como veremos enseguida, de echo no tendremos que ser unos gurus de DOM y SAX para poder trabajar con XML desde Java.




Donde conseguir JDOM




En www.jdom.org podremos descargar tanto el API como la documentación que necesitemos. Antes de que se me olvide, la licencia es open source. :-)



Como JDOM fue diseñado usando List y Map de la API Java 2 Collections, tendremos que utilizar el jdk 1.2 o si usas el jdk 1.1 deberás de instalar la librería Collections.




Estructura de JDOM




El API está formado por 5 packages. De entre ellas comentamos lo siguiente que será mas que suficiente para utilizar el API.




  • El package org.jdom destacamos las clases: Document que representará el documento XML, Element que representará el elemento o etiqueta que forma el documento, y la clase Attribute que como bien imaginaras representa los atributos que puedan tener los elementos.


  • El package org.jdom.adapters albergará todas las clases adaptadoras (ver patrón de diseño Adapter, Thinking in patterns) ya que no todos los parsers DOM tienen la misma API. Mas tarde quedara mas claro su función.


  • El package org.jdom.input albergara las clases builder para construir los documentos XML.


  • El package org.jdom.output albergara las clases que utilizaremos para dar salida a nuestra clase Document.







Un poco de teoría




Como dije al principio del articulo JDOM usaba los parsers para hacer su trabajo, pues bien, para decirle a JDOM que parser utilizar utilizaremos uno de los siguientes métodos:




public SAXBuilder(String parserClass, boolean validation)



El primer parámetro es el parser que vamos a utilizar, por defecto se utilizará el parser Xerces.



El segundo parámetro es para decirle si queremos que el parser cumpla sus obligaciones de validación.




public DOMBuilder(String adapterClass, boolean validation)



El primer parámetro es la clase adaptadora que vamos a utilizar para el parser que utilizaremos .



El segundo parámetro es igual que el del SAXBuilder.



Ahora al builder le daremos la orden de parsear el documento XML con el método build(), cuya forma es:




Document build(File file)



Muy bien ya tenemos el documento almacenado en la clase Document. Finalmente vamos a aprender unos cuantos métodos mas para recuperar la información que deseemos:




Este método pertenece a la clase Document




Element getRootElement(); //cojer el nodo raiz del documento.



Estos métodos pertenecen a la clase Element:




String getText();
//Capturar el texto de una etiqueta o elemento.
List getChildren();
//Coger todos los elementos que cuelgan del Element.
List getChildren(String nombre);
//Coger todos los elementos que tengan ese nombre
List getMixedContent();
//Para recuperar todo(comentarios, PIs, elementos,...)
// de lo que cuelga del Element.
Element getChild (String nombre);
//Coger el primer hijo que tenga ese nombre.
String getAttributeValue(String nombre);
//Coger el valor del atributo que pasamos como parámetro.
Attribute getAttribute(String nombre);
//Coger el atributo que tenga ese nombre y para recuperar
//el valor de ese atributo se
//utilizaría el método del attribute: String getValue();



Nuestro primer programa




Dado el siguiente documento XML:




<?xml version="1.0"?>
<liga tipo="Champions League">
<equipo>
<club valoracion="10" ciudad="Bilbao">Athletic Club Bilbao</club>
<presidente>Uria</presidente>
<plantilla>
<nombre>Julen Guerrero</nombre>
<nombre>Joseba Etxeberria</nombre>
<nombre>Ismael Urzaiz</nombre>
</plantilla>
</equipo>
<equipo>
<!-- no os piqueis ;-) -->
<club valoracion="5" ciudad="Madrid">Real Madrid</club>
<presidente>Mandamas</presidente>
<plantilla>
<!-- no pongo nombres propios por si acaso -->
<nombre>Bota de oro</nombre>
<nombre>Milloneti</nombre>
<nombre>Canterano quemado</nombre>
</plantilla>
<conextranjeros/>
</equipo>
<arbitros>
<nombre>No doy una</nombre>
<nombre>Rafanomejodas</nombre>
</arbitros>
</liga>



Vamos a hacer un programa que lo lea y nos muestra cierta información. Este sería el codigo:




import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;

public class Ejemplo {

public static void main(String[] args) {
try {
SAXBuilder builder=new SAXBuilder(false);
//usar el parser Xerces y no queremos
//que valide el documento
Document doc=builder.build("liga.xml");
//construyo el arbol en memoria desde el fichero
// que se lo pasaré por parametro.
Element raiz=doc.getRootElement();
//cojo el elemento raiz
System.out.println("La liga es de tipo:"+
raiz.getAttributeValue("tipo"));
//todos los hijos que tengan como nombre plantilla
List equipos=raiz.getChildren("equipo");
System.out.println("Formada por:"+equipos.size()+" equipos");
Iterator i = equipos.iterator();
while (i.hasNext()){
Element e= (Element)i.next();
//primer hijo que tenga como nombre club
Element club =e.getChild("club");
List plantilla=e.getChildren("plantilla");
System.out.println
(club.getText()+":"+"valoracion="+
club.getAttributeValue("valoracion")+","+
"ciudad="+club.getAttributeValue("ciudad")+","+
"formada por:"+plantilla.size()+"jugadores");
if (e.getChildren("conextranjeros").size()==0)
System.out.println("No tiene extranjeros");
else System.out.println("Tiene extranjeros");

}
// Dejamos de mano del lector el sacar el nombre
//de los arbitros, animate!!
}catch (Exception e){
e.printStackTrace();
}
}
}



Conclusión




Como hemos visto el leer documentos XML y sacar la información de dicho documento es un trabajo realmente fácil con JDOM, como veremos en el siguiente articulo el crear documentos con esta API no es mucho mas complicado.
















Javier Teso, actualmente está cursando 5º de Ing. Informática de San Sebastián.



Para cualquier duda o comentario: jte_job_ARROBA_hotmail.com ó jabotxa_ARROBA_latinmail.com