JAVA API REFLECTION usando reflection

La libreria estandar J2SE que viene con la distribucion de java nos ofrece varios paquetes de utilidades entre los que encontramos reflection.

Mediante el API reflection podemos acceder de forma abstracta a objetos que aunque conocemos ni su tipado, ni sus metodos ni otras cosas en tiempo de ejecucion podemos analizarla e interactuar con ella.

Es usado en muchos frameworks para buscar clases con anotaciones, clases que implementen interfaces, conocer sus metodos, sus retornos, etc.....

En resumen, que mediante reflection podemos acceder a cualquier objeto y obtener informacion de él, asi que como interactuar con él y todo en tiempo de ejecucion.

Os pongo aqui un ejemplillo de una clase que usa el API reflection para acceder a un objeto y analizarlo.
Saca trazas por consola de la info que obtiene e invoca a los metodos. Es muy sencillo, pero podeis ver el potencial que tiene el uso de reflection.

Podeis pasarle cualquier clase que creeis vosotros y ver como la analiza, yo de momento, cree una clase sencilla para ejemplificar el ejemplo.

ObjectInspector.java

 import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;



//Clase modelo que representa un coche
class Coche{
  
    private String nombre;
    private String color;
    private int precio;
    public String getNombre() {
        return nombre;
    }
    public String getColor() {
        return color;
    }
    public int getPrecio() {
        return precio;
    }

    public Coche (String nombre, String color, int precio){
        this.nombre= nombre;
        this.color= color;
        this.precio= precio;
    }
}



public class ObjectInspector {

    /**
     * Lee un objeto no tipado, accede a sus metodos y
     * los ejecuta
     * @param o
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws Exception
     */
    private void inspectObject (Object o) {
        //A partir de la clase del objeto sacamos la info
        //de metodos y propiedades, luego solo necesitamos
        //invocar a esos metodos en el scope de ese objeto
      
        //1.Obtenemos la clase
        Class clazz = o.getClass();
        //2.recorremos sus methods
        for (int i=0; i< clazz.getMethods().length;i++){
            System.out.println("/************************************/");
            Method mthd = clazz.getMethods()[i]; //obtenemos la info del metodo
            String mthd_name = mthd.getName();
            //Que retorno tiene
            String mthd_return_type = mthd.getReturnType().getName();
            //Modificadores de acceso que tiene
            String mthd_modifiers = Modifier.toString(mthd.getModifiers());
            //Args que acepta, si no es getter
            Class[] params = mthd.getParameterTypes();
            StringBuffer lst_params = new StringBuffer();
            for(int z=0;z < params.length;z++){
                lst_params.append(params[z].getName() + " ");
            }
            //Trazas
            System.out.println("Method--> "+mthd_modifiers+ " " +mthd_return_type  +" " + mthd_name +"("+ lst_params +")");
          
            //ejecutamos el metodo pasandole el objeto en el que queremos
            //invocarlo (o), como args paso null,porque no tenemos args ya que
            //solo nos interesan los getters
          
          
            try {
                Object value = (Object)mthd.invoke(o, null);
                System.out.println("returns --> " + value);
            } catch (IllegalArgumentException e) {
                System.out.println("Argumentos al metodo no validos, acepta "+ lst_params);
              
            } catch (IllegalAccessException e) {
                System.out.println("Este metodo no es accesible " + mthd_modifiers);
            } catch (InvocationTargetException e) {
                System.out.println("Error al invocar, no devuelve valor , es  "+ mthd_return_type);
            }
          
        }
    }
  
  
  
    /**
     * @param args
     */
    public static void main(String[] args) {
      
        try {
            Coche a = new Coche("seat 600", "rojo", 750);
            new ObjectInspector().inspectObject(a);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}




Espero os haya dado un poco de vision sobre el asunto...

Comentarios

Publicar un comentario

Entradas populares de este blog

Subir campos Blob a BBDD (Oracle) con Java

Reiniciar usuario de SVN Subversion

Cucumber y Java - definiendo test de una manera amigable