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...
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...
Thanks
ResponderEliminar