Hay muchas formas de crear aplicaciones, se pueden utilizar distintos paradigmas de programación ( lógico, funcional, orientado a objetos…) o lenguajes de programación. Cada uno de ellos tiene similitudes (como opciones para leer o escribir ficheros, control de flujo, tratamiento de errores, estructuras para repetir determinadas operaciones…) aunque tienen notables diferencias que los hacen más adecuados para resolver unos determinados tipos de problemas.

Uno de los lenguajes de programación que más utilizo es Java con el IDE netbeans y maven como gestor de librerías.

INSTALACIÓN DE JAVA

La forma de instalar estas herramientas en linux es bastante sencilla, basta con teclear los siguientes comandos:

abian@casa:~$ sudo apt-get install sun-java6-* netbeans maven2

Es recomendable tener alguna variable de entorno llamada JAVA_HOME que apunte a la máquina virtual de java añadiendo la siguiente línea al archivo /etc/profile (para todos los usuarios de la máquina) o al archivo $HOME/.bashrc (solo para el usuario elegido):

export JAVA_HOME=/usr/lib/jvm/java-6-sun

Una vez que está todo instalado ya se pueden desarrollar programas con Java de forma normal.

PROGRAMACIÓN ORIENTADA A OBJETOS

La forma normal de desarrollar programas en un paradigma de programación orientada a objetos es que primero se crea un objeto del tipo que queramos y luego se ejecutan métodos sobre él. Por ejemplo:

String alberto = new String();

int logitud = alberto.length();

longitud de una cadena de texto

longitud de una cadena de texto

De esta manera se puede obtener la longitud de la cadena de texto gracias a que la función “length” ha sido declarada en la clase java.lang.String. Una de las características de Java es que todos las clases heredan de la super clase java.lang.Object. De esta forma se pueden crear objetos del tipo Object para posteriormente hacer un cast al objeto que más nos convenga:

java.lang.Object abian;

abian = (String) new String(“Abian”); //la clase a la que se hace el cast está resaltada en negrita

El hecho de poder hacer un cast después de haber declarado la variable aporta una gran flexibilidad, por ejemplo, a la hora de crear listas o colecciones de objectos.

ArrayList<String> listaDeStrings=new ArrayList<String>();

Podría convertirse en:

ArrayList<Object> listaDeCosas = new ArrayList<Object>();

Esta es la explicación “demasiado” informal de polimorfismo.

API REFLEXIVA

Siguiendo el paradigma de la orientación a objetos, debemos indicar de qué clase es cada objeto que estamos creando en tiempo de compilación. Pero, ¿Qué pasa si queremos crear un objecto y hacer el cast de forma dinámica? Es decir, ¿se puede establecer en un archivo de configuración la clase que quiero cargar y luego ejecutar los métodos de esa clase? El API reflexiva permite ese tipo de cosas, es la siguiente vuelta de tuerca.

Para utilizar el API reflexiva hay que hacer uso de tres clases Class, Object, Method (por legibilidad de código puede ser útil Constructor):

//el tipo se podría coger de una archivo de configuración
String nombreClaseJava = “java.lang.String”;
//estas tres líneas serían las equivalentes a hacer “new String()”
Class claseJava = Class.forName(nombreClaseJava);
Constructor constructor = claseJava.getConstructor();
Object objeto = constructor.newInstance();
//Estas dos líneas serían las equivalentes a hacer “cadena.lenght()”
Method metodo = claseJava.getMethod(“length”);
Object longitud = metodo.invoke(objeto);

Por supuesto hay un buen número de excepciones que deben ser tratadas, en este caso: InstantiationException,IllegalAccessException, IllegalArgumentException, NoSuchMethodException, SecurityException, ClassNotFoundException.

Si es necesario pasar parámetros al objeto que estamos creando hay que utilizar un array que contendrá el tipo de cada parámetro y otro array que contendrá el parámetro en sí como se muestra en las modificaciones con negrita al código anterior:

String nombreClaseJava = “java.lang.String”;
Class claseJava = Class.forName(nombreClaseJava);
Class[] parType = new Class[1];
Object[] argList = new Object[1];
parType[0] = String.class;
argList[0] = “Alberto abian”;
Constructor constructor = claseJava.getConstructor(parType);
Object objeto = constructor.newInstance(argList);
Method metodo = claseJava.getMethod(“length”);
Object longitud = metodo.invoke(objeto);
System.out.println(“clase de la variable objeto: ” + objeto.getClass());
System.out.println(“contenido de objecto: ” + objeto);
System.out.println(“contenido de longitud: ” + longitud);

Si todo ha ido bien hasta aquí, se debería ver por pantalla:

clase de la variable objeto: class java.lang.String
contenido de objecto: Alberto abian
contenido de longitud: 13


¿VENTAJAS E INCONVENIENTES?

Como en todas las tecnologías hay ventajas e inconvenientes. En mi opinión, la mayor ventaja es la flexibilidad a la hora de ejecutar el código. Se puede utilizar un archivo de configuración que contenga las clases o funciones que se van a utilizar en el programa sin necesidad de recompilar. Sin embargo, no está exenta de problemas:

  • Rendimiento: La máquina virtual de java no puede optimizar el código ya no sabe a qué clase pertenece.
  • Seguridad: El API reflexiva necesita permisos especiales de ejecución que pueden no estar disponibles en todos los sistemas. Además, el API reflexiva permite acceso a variables y métodos declarados como privados, algo que no se podría hacer en un entorno no-reflexivo.

Espero que os haya resultado de interés.