Eu sempre fui um verdadeiro admirador do pacote java.lang.reflect, não nego… Através dele (suas classes) pode-se realizar maravilhas!! ;pp
E agora, vejam que legal!! Para os que precisarem de acessar métodos, atributos, construtores, anotações (annotations) e classes internas inacessíveis (a priori), por conta de sua restrição de acesso (vide os modificadores private, protected e default) pode utilizar as features(hahahah!! @since JDK1.1) fornecidas pela classe Class e as filhas de java.lang.reflect.
Temos X:
public class X {
private double xValue;
public X(){
xValue = Double.MAX_VALUE;
}
private void shout(){
System.out.println(“ARrrRRrrR!!”);
}
public Y getY(){
return new Y();
}
private class Y {
public String getSomeString(){
return “Java Reflection”;
}
}
}
Farei agora uma pergunta com relação a um atributo inacessível, mas que poderia ser feita também se referindo a um método ou classe interna privados (ou qualquer outro modificador que os tornassem inacessíveis). Como faríamos para acessar o atributo xValue de X?? Se você respondeu para si mesmo “Abro o código, crio um método public void setXValue e acabou-se!!” esse post é abrirá uma janela na sua vida! How poetic!!
Agora vejam abaixo a solução:
public static void main(String[] args) {
try {
X x1 = new X();
Method m1 = X.class.getDeclaredMethod(“shout”);
m1.setAccessible(true);
m1.invoke(x1);
Field field1 = X.class.getDeclaredField(“xValue”);
field1.setAccessible(true);
System.out.println(field1.get(x1));
Object yObject = X.class.getMethod(“getY”).invoke(x1);
Method m2 = yObject.getClass().getMethod(“getSomeString”);
System.out.println(m2.invoke(yObject));
} catch (Exception e) {
e.printStackTrace();
}
}
O “pulo do gato” aqui é o seguinte… há métodos na Class que retornam somente os métodos acessíveis que é o getMethod e há também seu “irmão” que retorna todos os métodos, quer eles sejam privados, protected, default ou public, que é o getDeclaredMethod. Há também os relativos a atributos (getField e getDeclaredField), classes internas (getClasses e getDeclaredClasses), construtores (getConstructore getDeclaredConstructor) e por fim anotações (getAnnotations e getDeclaredAnnotations).
Uma vez retornados, realiza-se uma chamada ao método setAccessible passando como parâmetro true bastando isso para torná-lo acessível. Então lembre-se, a partir de hoje, pense duas vezes em abrir código, modificá-lo e recompilá-lo!! Há situações em que uma simples reflexão resolve.
Tags: classes, default, fields, JAVA, methods, private, protected, Reflection, visibility
September 11, 2009 at 16:41 |
[...] public class {} developer adventures, developer stuff « Acessando métodos / atributos / classes privadas? Reflection!! [...]