Clases de Utilidad Java VII: Reflection

Bueno, pues vamos a avanzar un poco más en nuestras clases de utilidad y hoy vamos a poner unos cuantos métodos con los que poder usar el API reflection.

Éste API es muy usado dentro de la comunidad y es una herramienta muy potente a la hora de invocar métodos o clases por ejemplo definidos en base de datos.

Obtener una clase a partir de un nombre:

/**

* Obtiene una clase a partir del nombre de la misma.

*

* @param clazz La cadena que identifica la clase que se quiere obtener.

*

* @return La clase correspondiente si se ha encontrado, y sino una excepción PLNException.

* @throws La excepción Exception.

*/

@SuppressWarnings("unchecked")

public static Class getClass (String clazz) throws Exception {

Class result = null;

try {

result = Class.forName(clazz);

} catch (ClassNotFoundException e) {

log.error("No se encuentra la clase " + clazz, e);

throw new Exception("No se encuentra la clase " + clazz,e);

} catch (NullPointerException e) {

log.error("Se ha pasado un nombre de clase null ", e);

throw new Exception("Se ha pasado un nombre de clase null ",e);

}

return result;

}

Obtener el método de una clase (solo los visibles):

/**

* Dada una clase, una cadena que identificará al método y la lista de parámetros, devuelve el

* método público correspondiente de la clase, y si éste no existiera o si se encontrara algún

* problema, se lanzará la excepción Exception.

*

* @param clazz

* La clase donde se pretende encontrar el método.

* @param method

* La cadena que representa el método a buscar en la clase.

* @param params

* La lista de parámetros que necesita el método.

*

* @return El método en cuestión o una excepción Exception.

* @throws La excepción Exception.

*/

@SuppressWarnings("unchecked")

public static Method getMethod (Class clazz, String method, List<String> params) throws Exception {

Method result = null;

if (params == null){

log.error("Parámetros nulos ");

throw new Exception("Parámetros nulos ");

}

Class [] parametros = new Class[params.size()];

int i = 0;

for (String className : params) {

parametros [i++] = getClass(className);

}

try {

result = clazz.getMethod(method, parametros);

} catch (SecurityException e) {

log.error("Error en la seguridad " + method, e);

throw new Exception("Error en la seguridad " + method, e);

} catch (NoSuchMethodException e) {

log.error("No se encuentra el método " + method, e);

throw new Exception("No se encuentra el método " + method, e);

} catch (NullPointerException e) {

log.error("Se han pasado parámetros null ", e);

throw new Exception("Se han pasado parámetros null ",e);

}

return result;

}

Obtener el método de una clase (todos y cada uno sean visibles o no):

/**

* Dada una clase, una cadena que identificará al método y la lista de parámetros, devuelve el

* método correspondiente de la clase, sea o no público, y si éste no existiera o si se

* encontrara algún problema, se lanzará la excepción Exception.

*

* @param clazz

* La clase donde se pretende encontrar el método.

* @param method

* La cadena que representa el método a buscar en la clase.

* @param params

* La lista de parámetros que necesita el método. Un ejemplo sería "java.util.List".

*

* @return El método en cuestión o una excepción Exception.

* @throws La excepción Exception.

*/

@SuppressWarnings("unchecked")

public static Method getDeclaredMethod (Class clazz, String method, List<String> params) throws Exception {

Method result = null;

if (params == null){

log.error("Parámetros nulos ");

throw new Exception("Parámetros nulos ");

}

Class [] parametros = new Class[params.size()];

int i = 0;

for (String className : params) {

parametros [i++] = getClass(className);

}

try {

result = clazz.getDeclaredMethod(method, parametros);

} catch (SecurityException e) {

log.error("Error en la seguridad " + method, e);

throw new Exception("Error en la seguridad " + method, e);

} catch (NoSuchMethodException e) {

log.error("No se encuentra el método " + method, e);

throw new Exception("No se encuentra el método " + method, e);

} catch (NullPointerException e) {

log.error("Se han pasado parámetros null ", e);

throw new Exception("Se han pasado parámetros null ",e);

}

return result;

}

Invocar un método de una clase:

/**

* Método encargado de, dada una clase y un método de la misma, con sus correspondientes

* parámetros, invocar el mismo, obteniendo como resultado en la clase Object, el resultado

* de su ejecución.

*

* @param className

* La cadena que representa la clase que se quiere manejar.

* @param methodName

* La cadena que representa el método que se quiere invocar.

* @param params

* La lista de parámetros que se tienen que pasar al método para realizar su ejecución.

*

* @return El objeto que retorna la ejecución del método.

* @throws Exception

*/

public static Object invoke (String className, String methodName, List<Object> params) throws Exception {

Object result = null;

Object instance = null;

Method metodo = null;

List<String> lParametros = new ArrayList<String> ();

for (Object object : params) {

lParametros.add(object.getClass().getName());

}

try {

instance = getClass(className).newInstance();

metodo = getDeclaredMethod(getClass(className), methodName, lParametros);

metodo.setAccessible(true);

result = metodo.invoke(instance, params.toArray(new Object[params.size()]));

} catch (SecurityException e) {

log.error("Error en la seguridad " + instance, e);

throw new Exception("Error en la seguridad " + instance, e);

} catch (IllegalArgumentException e) {

log.error("IllegalArgumentException invoke ", e);

throw new Exception("IllegalArgumentException invoke ", e);

} catch (IllegalAccessException e) {

log.error("IllegalAccessException invoke ", e);

throw new Exception("IllegalAccessException invoke ", e);

} catch (InvocationTargetException e) {

log.error("InvocationTargetException invoke ", e);

throw new Exception("InvocationTargetException invoke ", e);

} catch (InstantiationException e) {

log.error("InstantiationException a la hora de instanciar la clase ", e);

throw new Exception("InstantiationException a la hora de instanciar la clase ", e);

}

return result;

}

Esto se puede mejorar mucho con el uso de anotaciones, así es que cualquier propuesta siempre es bien recibida!

Deja un comentario