About me

asdfasdf aasdf Read more about me »

Keep in touch

RSS Feed Twitter Facebook Delicious

Subscribe via Email

Reflexión en Java III, Acceso y modificación de ...

April 30th, 2010 by PakoS received No Comments »

En el post anterior mostré como obtener las propiedades de una clase, ahora veremos cómo colocar valores y obtener los valores almacenados en las propiedades de un objeto de una clase desconocida, recuerden que la reflexión solo nos permite acceso a los recursos públicos de las clases.

Para iniciar nuevamente modifico un poco las cases que nuestro programa observará mediante reflexión

A.java

/**
 *
 * @author jfcodiaz
 * wariodiaz@gmail.com
 * www.devtics.com.mx
 * 17/04/2010
 */
public class A {
    public int n1;
    public int R;
    public int n2;
    public String nombre;
    public B b;
    @Override
    public String toString() {
        return "Esto es una clase A";
    }
    public void saludo(){
        System.out.println("Hola Mundo!");
    }
}

B.java

/**
 *
 * @author jfcodiaz
 * wariodiaz@gmail.com
 * www.devtics.com.mx
 * 15/04/2010
 */
public class B {
    public String propiedad1;
    public String propiedad2;
    @Override
    public String toString() {
        return "esto es una B";
    }
}

Solo he cambiado el acceso a R, en B a publico esto porque el objetivo de este post es mostrar el acceso, asignación y recuperación de las propiedades de una clase a través de reflexión lo cual solo se puede realizar con propiedades públicas.

Como vimos en el post anterior podemos saber el tipo de dato que almacena una determinada propiedad a través de objField.getType() el cual nos retornara un objeto Class el cual de igual forma podremos analizar si vamos al método .toString() del objeto devuelto podremos ver que nos retorna una cadena con el tipo de dato si este es nativo(int, short, boolean, char, float, double, byte, long) o bien la cadena “class”, un espacio y el nombre completo de la clase en el classPath (esto se vio en el ejemplo anterior)

La clase Class nos permite obtener su nombre con objClass.getName() el cual nos retorna el nombre de la clase o su ruta en el classpath al igual que si se trata de un tipo nativo el tipo de dato, con esto podremos crear un programa que analice la clase e identificar qué tipo de dato debemos colocar en cada una de las variables.

Para colocar un valor los objetos Field (java.lang.reflect.Field) cuentan con los siguientes métodos de los cuales sus nombres son muy descriptivos.

- set(Object obj, Object value) void
- setBoolean(Object obj, boolean z) void
- setByte(Ojbect obj, byte b) void
- setChar(Object obj, char c) void
- setDouble(Object obj, double d) void
- setFloat(Object obj, float f) void
- setInt(Object obj, int i) void
- setLong(Object obj, long l) void
- setShort(Object obj, short s) void

El primer primer parámetro es el objeto en el que se buscara la propiedad y se le asignara el valor del Segundo parámetro, los setter son para los tipos de datos nativos, para propiedades que sean objetos se utiliza el método set().

Para recuperar los datos utilizamos los siguientes métodos getters de los objetos Field también muy descriptivos

-get(Object obj) Object
-getBoolean(Object obj) boolean
-getByte(Object obj) byte
-betChar(Object obj) char
-getDouble(Object obj)double
-getFloat(Object obj) float
-getInt(Object ojb) int
-getLong(Object obj) long
-getShort(Object obj) short

El único parámetro es el objeto donde se buscará la propiedad y de igual forma se utiliza cada getter segun el tipo de dato una vez si es que se sabe el tipo de dato que se obtendrá si no puede utilizar el método get y luego analizar el objeto para saber que tipo de dato es, todos los objetos en java tienen el método .getClass() el cual nos retorna un objeto Class con clase del objeto

Por ultimo dejo un ejemplo donde se analiza crea un objeto de una clases desconocida y si se encuentran propiedades String o int se llama a su setter y posteriormente se muestra el valor de todos los atributos de un objeto de la clases indicada por ultimo el programa nos pregunta el nombre de una propiedad para conocer su valor.

import java.lang.reflect.Field;
import java.util.Scanner;
/**
 *
 * @author jfcoDiaz
 * www.devtics.com.mx
 * 18/04/2010
 *
 */

public class Reflexion3 {
    public static void main(String[] args) {
        String nombreClase = "";
        Class _class;
        Object obj;
        Scanner sc = new Scanner(System.in);
        Field[] propieties;
        try {
            nombreClase =  sc.nextLine();
            _class = Class.forName(nombreClase);
            obj = _class.newInstance();
            propieties = _class.getFields();
            for (int i = 0; i < propieties.length; i++) {
                Field field = propieties[i];

                String nameType = field.getType().getName();
                if (nameType.equals("int")) {
                    System.out.println("Escribe El Valor  que guardara en "+field.getName()+" (Solo Numeros Enteros) " );
                    field.set(obj, Integer.parseInt(sc.nextLine()));
                } else if (nameType.equals("B")) {
                    field.set(obj, new B());
                } else if (nameType.equals("java.lang.String")) {
                    System.out.println("Escribe El Valor que guardara " + field.getName());
                    field.set(obj, sc.nextLine());
                } else {
                    System.out.println("Este programa no soporta la asignacion de " + nameType);
                }
            }
            for (int i = 0; i < propieties.length; i++) {
                Field field = propieties[i];

                System.out.println(field.getName() + " vale " + field.get(obj).toString());
            }
            System.out.println("Escribe el nombre de una propiedad para conocer su valor");
            Field field = _class.getField(sc.nextLine());
            System.out.println("La Propiedad " + field.getName() + " vale " + field.get(obj).toString());
        } catch (InstantiationException ex) {
            System.out.println("Error al Crear el Objeto");
        } catch (IllegalAccessException ex) {
            System.out.println("Error al Crear el Objeto");
        } catch (ClassNotFoundException ex) {
            System.out.println("La " + nombreClase + " Clase Indicada no Existe en el ClassPath");
        } catch (NoSuchFieldException ex) {
            System.out.println("El objeto no cuenta con la propiedad indicada");
        } catch (SecurityException ex) {
            System.out.println("No se tiene acceso a la clase o propiedad");
        }
    }
}

Con esto ya he mostrado como analizar una Clase y obtener sus propiedades . crear un objeto de esta clase desconocida e interactuar con sus propiedades, en el siguiente post mostrare como conocer los métodos de una clase mediante reflexión.

Códigos Fuentes de ejemplos en Netbeans 6.8

<< Reflexión en Java I, Instancia una clase desconocidas en tiempo de ejecución
<< Reflexión en Java II, Obtener propiedades de una clase desconocidas en tiempo de ejecución

www.devtics.com.mx

Reflexión en Java II, Obtener propiedades de una...

April 28th, 2010 by PakoS received 1 Comment »

En el pos anterior mostré como instanciar un par de clases sencillas según una cadena obtenida desde el teclado esto sin saber que teclearía el usuario y sin usar if’s ni switch si no con la reflexión que es el mecanismo por el cual podemos conocer los detalles y manejar en tiempo de ejecución de una clase “desconocida” en codificación.
En este post mostrare como obtener información de las propiedades de nuestra clase.
Para este post he modificado las clases A y B, agregándole propiedades
classA

/**
 *
 * @author jfcodiaz
 * www.devtics.com.mx
 * 17/04/2010
 */
public class A {
    public int n1;
    private int R;
    public int n2;
    public B b;
    @Override
    public String toString() {
        return "Esto es una clase A";
    }
    public void saludo(){
        System.out.println("Hola Mundo!");
    }
}

classB

/**
 *
 * @author jfcodiaz
 * wariodiaz@gmail.com
 * www.devtics.com.mx
 * 15/04/2010
 */
public class B {
    public String propiedad1;
    public String propiedad2;
    @Override
    public String toString() {
        return "esto es una B";
    }
}

Como ya se menciono anteriormente lo primero que tenemos que hacer es obtener la clase y almacenarla en un objeto tipo Class para esto hacemos uso del método estático Class.forName(Stirng ClassName), la cual recibe como String el nombre de la Clase.

Java a través de la clase java.lang.reflect.Field representa las propiedades públicas una clase, solo tenemos acceso a las propiedades y métodos público de la clase por obvias razones no podemos ver los métodos y propiedades privadas.
Lo primero que tenemos que hacer es recuperar nuestra clase:

 Class _class = Class.forName("A"); 

Para obtener una propiedad la cual conocemos su nombre podremos usar el método _class. getField(String nombrePropiedad), en cambio si no conocemos el nombre de las propiedades que es lo más lógico en este tema. Podremos obtener una lista de las propiedades con _class.getFields() el cual nos retorna un array de Fields con las propiedades de la clase.

Field properties[] = _class.getFields();

Para saber el identificador del Field consultamos el método .getName del objeto Field
Podemos saber el tipo de dato de la propiedad consultado al método getType() del objeto Field, si es un dato primitivo nos retornara una cadena con el tipo de dato, si es una objeto no indicará la clase en el Classpath:
Reflexion2.java:

import java.lang.reflect.Field;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 *
 * @author Pakos
 * www.devtics.com.mx
 * 17/04/2007
 */
public class Reflexion2 {
    public static void main(String[] args) {
        try {
            Class _class = Class.forName("B");
            Field properties[] = _class.getFields();
            for (int i = 0; i < properties.length; i++) {
                Field field = properties[i];
                System.out.println(field.getName() +" > "+field.getType());
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Reflexion2.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Out:

propiedad1 > class java.lang.String
propiedad2 > class java.lang.String

Ahora si modificamos la clase para que liste la clase A esta debería de ser la salida:

Class _class = Class.forName("A");

Out:

n1 > int
n2 > int
b > class B

Observe que en no se lista la propiedad R de la clase A ya que esta es una propiedad privada

Con esto termino este post. En el próximo mostrare como podemos modificar y/o consultar el valor de las propiedades.
Código Fuente en proyecto NetBeans6.8

<<Reflexión en Java I, Instancia una clase desconocidas en tiempo de ejecución

Reflexión en Java I, Instancia una clase descono...

April 27th, 2010 by PakoS received 4 Comments »

La Reflexión es el mecanismo mediante el cual java puede conocer clases ya compiladas y nos permite conocer cualquier clase con tan solo conocer su nombre así como crear instancia de los objetos e interactuar con los métodos de la misma, este puede tener diversas aplicaciones, en un siguiente post les mostrare como aprovecho esta ventaja en la programación en Web de Java por ahora me limito a mostrar algo de la API, en este post solo mostrare como crear la instancia de un objeto en post posteriores mostrare como obtener información de la clase y interactuar con sus métodos.
Para poder instanciar una clase con solo conocer su nombre y o ubicación en el classpath, ojo la clase tiene que estar en el claspath algo lógico por que si no lo esta java no la encontrará.

Para Ejemplificar creare dos clase A y B:

Class A

public class A {
    @Override
    public String toString() {
        return "Esto es una clase A";
    }
}

Class B

public class B {
    @Override
    public String toString() {
        return "esto es una B";
    }

}

Como observara solo he definido el método toString() que sobrescribe el método heredado desde java.lang.Object, este método se invoca al tratar de convertir un objeto a String por ejemplo al querer imprimirlo con un System.out.println()
Para Obtener la clase desde un string haremos uso del método estático forName() de la clase Class, esta clase nos provee distintos métodos para obtener información de una clase, si han manejado drivers jdbc recordaran haber utilizado este método.
Ejemplo :

Class _class = Class.forName(“A”);

Con esto se almacena la clase (el molde, no la instancia) de la clase A, observe que se envía una cadena esto hace que esto pueda ser dinámico en tiempo de ejecución ya que podemos tener una variable y esta enviarla al Class.forName, si la clase no se encuentra se genera una excepción tipo ClassNotFoundException .
Una ves que tenemos la clase podremos llamar a su constructor por defecto (el que no recibe ningún parámetro, constructores con parámetros los mostrare en otro post)

Para crear la instancia haremos uso del método .newInstance(); del objeto Class que almacene nuestra clase en nuestro ejemplo _class, este métodos pueden generar excepciones tipo InstantiationException, IllegalAccessException

Object obj=_class.newInstance();

Las excepciones las podemos manejar con campos try/catch o bien agregando throws al inicio de nuestro método.
Para ver que realmente estamos instanciando un objeto del tipo marcado en Class.forName, mandare imprimir el objeto.

System.out.println(obj);

Con esto mando implícitamente el método .toString(), podrán observar la salida en la consola y debería de mostrar el mensaje:

“Esto es una clase A”

Aquí el código de la clase que usa la reflexión
reflexion1.java

public class refexion1 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class _class = Class.forName("A");
        Object obj = _class.newInstance();
        System.out.println(obj);

    }
}

Ahora cambie el parámetro de Class.forName a “B”, y pruebe observara que el mensaje ha cambiando por

“esto es una B”

Por último modifico la clase para que atreves del teclado el usuario me indique que clase instanciar.

import java.util.Scanner;
public class refexion1 {
    public static void main(String[] args) {
        System.out.println("Escribe A o B");
        String strClase = new Scanner(System.in).nextLine();
        try {
            Class _class = Class.forName(strClase.toUpperCase());
            Object obj;
            try {
                obj = _class.newInstance();
                System.out.println(obj);
            } catch (InstantiationException ex) {
                System.out.println("Error al Instaciar laClase");
            } catch (IllegalAccessException ex) {
                System.out.println("Error al Instaciar laClase");
            }
        } catch (ClassNotFoundException ex) {
            System.out.println("La Clase No existe");
        }
    }
}

Espero este post allá despertado su interés.. próximamente les digo como obtener información, instanciar con constructores con parámetros, obtener información de los métodos y sus parámetros y como interactuar con ellos.

Código fuente en proyecto de netBeans 6.8 http://www.megaupload.com/?d=NU41A5D0

>> Reflexión en Java II, Obtener propiedades de una clase desconocidas en tiempo de ejecución

Ya hay Street view de Google Maps para León, Gto ...

April 20th, 2010 by PakoS received No Comments »

Pues solo para compartir via @kLandin, me he enterado que ya podemos disfrutar del street view de León Gto(la ciudad en la que radico :) ), al igual que otras ciudades del país ya podemos hacer nuestro recorridos virtuales hasta los lugares lejanos que que conocemos o no conocemos o queremos recordar (yo fui a zamora Mich. :$ donde también son de los afortunados en tener disponible este servicio), anteriormente solo teníamos street view en el D.F, Guadalajara y creo Cancún, con esto se cubre gran parte del centro del país con este servicio de google, muy eficiente para ya dar con lugares o destinos que no conocemos ideal para cuando hay una peda y no sabemos donde es la casa, hacemos el map y ya podemos ver exactamente donde será la fiesta… o cuando no citemos con alguien,
bueno en lo que disfrutaba del servicio y hacia un recorrido virtual a los lugares que quería visitar. intente visitar mi universidad (UTL) pero el google no paso :( solo llego a la esquina y y no paso frente de.. misma suerte tubo mi CONALEP en Silao donde también ya esta disponible el street view, creo que en esos entonces las calles estaban con obras y por eso el google car no pudo pasar y pues no les toco salir en google, para Romita solo hay una calle en street view (de donde soy originario) así que allá todavía nos toca seguir esperando

bueno me encontre con la primera curiosidad o para mi lo es… por la carreta que pasa por UTL existen infinidad de espectaculares, buscando la forma de ver como de que tiempo son las imagenes vi un espectacular el cual tiene publicitaba un evento, me quise acercar para ver la fecha.. y doy un clic(a la izquieda) y me cambiaron el espectacular :S.. jeje una muestra que el google car pasa en diferentes ocasiones por el mismo lugar que tan distante estuvo eso pues no se por que el segundo anuncio del espectacular no tiene fecha… bueno el street view para que se den su viaje virtual a donde plazcan :) y pues a buscar curiosidades también…