Una tendencia muy común cuando se empieza a programar en Java es pensar que si definimos algo como private no será ni visible, ni accesible para los futuros usuarios de la clase. El objetivo de este breve artículo es mentalizar a quienes estén empezando de no incluir en el código aquello que no quieran que pueda ser visualizado.
Quiero dejar claro que no me hago responsable del uso, bueno o malo, que se le de a la información expuesta en este artículo.
Desde su JDK 1.1 contamos con el paquete java.lang.reflect, en el cual podemos encontrar clases e interfaces para visualizar información sobre clases y objetos en tiempo de ejecución. No tengo intención de tratar el tema en profundidad, pero a quien le interese le recomiendo visitar los siguientes enlaces:
- http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/package-summary.html#package_description
- http://tutorials.jenkov.com/java-reflection/index.html
Para ejemplificar lo que he dicho más arriba he creado dos clases:
- La que contiene los atributos y métodos que creemos seguros, que la he llamado ClasePrivada.
- La que accede a los métodos y atributos private de la anterior, que la he llamado Cotilla.
package es.ekiwi.ingenios;
public class ClasePrivada {
private static String clave="Esta es la clave";
private String direccion="Esta es la direccion";
private String concatena(){
return this.direccion+this.clave;
}
public void muestra(){
System.out.println(this.concatena());
}
}
Es una clase totalmente absurda, pero por su sencillez permite ilustrar a la perfección lo que estoy explicando.
Por otro lado el código de la clase Cotilla es:
package es.ekiwi.ingenios;
import java.lang.reflect.*;
import es.ekiwi.ingenios.ClasePrivada;
public class Cotilla {
public static void listadorDeAtributos(ClasePrivada objeto) throws IllegalArgumentException, IllegalAccessException{
System.out.println("A continuación se muestran los " +
"atributos y su contenido");
Class clase =objeto.getClass();
Field[] atributos =clase.getDeclaredFields();
String separador="*************************************";
for(int i=0;i<atributos.length;i++){
System.out.println(separador);
System.out.println("\tNombre: "+atributos[i].getName());
System.out.println("\tTipo: "+atributos[i].getType());
atributos[i].setAccessible(true);
System.out.println("\tContenido: "+atributos[i].get(objeto));
}
}
public static void listadorDeMetodos(ClasePrivada objeto) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
System.out.println("A continuación se muestran los metodos y su tipo");
Class clase =objeto.getClass();
Method[] metodos=clase.getDeclaredMethods();
String separador="*************************************";
for(int i=0;i<metodos.length;i++){
System.out.println(separador);
System.out.println("\tNombre: "+metodos[i].getName());
System.out.println("\tTipo devuelto: "+metodos[i].getReturnType());
metodos[i].setAccessible(true);
}
}
public static void main(String[] args) {
ClasePrivada objeto = new ClasePrivada();
try {
listadorDeAtributos(objeto);
listadorDeMetodos(objeto);
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.lang.reflect.*;
import es.ekiwi.ingenios.ClasePrivada;
public class Cotilla {
public static void listadorDeAtributos(ClasePrivada objeto) throws IllegalArgumentException, IllegalAccessException{
System.out.println("A continuación se muestran los " +
"atributos y su contenido");
Class clase =objeto.getClass();
Field[] atributos =clase.getDeclaredFields();
String separador="*************************************";
for(int i=0;i<atributos.length;i++){
System.out.println(separador);
System.out.println("\tNombre: "+atributos[i].getName());
System.out.println("\tTipo: "+atributos[i].getType());
atributos[i].setAccessible(true);
System.out.println("\tContenido: "+atributos[i].get(objeto));
}
}
public static void listadorDeMetodos(ClasePrivada objeto) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
System.out.println("A continuación se muestran los metodos y su tipo");
Class clase =objeto.getClass();
Method[] metodos=clase.getDeclaredMethods();
String separador="*************************************";
for(int i=0;i<metodos.length;i++){
System.out.println(separador);
System.out.println("\tNombre: "+metodos[i].getName());
System.out.println("\tTipo devuelto: "+metodos[i].getReturnType());
metodos[i].setAccessible(true);
}
}
public static void main(String[] args) {
ClasePrivada objeto = new ClasePrivada();
try {
listadorDeAtributos(objeto);
listadorDeMetodos(objeto);
} catch (Exception e) {
e.printStackTrace();
}
}
}
A continuación se muestra una captura de la ejecución del código anterior:
En este ejemplo solo se ha hecho una visualización, pero hay métodos que permiten modificar los atributos, así como ejecutar métodos privados.

No hay comentarios:
Publicar un comentario