2009-10-12 8 views
77

¿Es posible en Java acceder al campo privado str mediante reflexión? Por ejemplo, para obtener el valor de este campo.¿Es posible en Java acceder a campos privados a través de la reflexión

class Test 
{ 
    private String str; 
    public void setStr(String value) 
    { 
     str = value; 
    } 
} 
+1

La pregunta habría mejorado mucho si incluía "Probé esto ..." con el código en cuestión. – duffymo

+0

La pregunta es una tontería: se ha preguntado y respondido algunas veces –

Respuesta

162

Sí, absolutamente lo es, suponiendo que tenga los permisos de seguridad adecuados. Use Field.setAccessible(true) primero si accede desde una clase diferente.

import java.lang.reflect.*; 

class Other 
{ 
    private String str; 
    public void setStr(String value) 
    { 
     str = value; 
    } 
} 

class Test 
{ 
    public static void main(String[] args) 
     // Just for the ease of a throwaway test. Don't 
     // do this normally! 
     throws Exception 
    { 
     Other t = new Other(); 
     t.setStr("hi"); 
     Field field = Other.class.getDeclaredField("str"); 
     field.setAccessible(true); 
     Object value = field.get(t); 
     System.out.println(value); 
    } 
} 

Y no, normalmente no deberías hacer esto ... está subvirtiendo las intenciones del autor original de la clase. Por ejemplo, puede haber una validación aplicada en cualquier situación donde el campo puede normalmente establecerse, u otros campos pueden cambiarse al mismo tiempo. Estás efectivamente violando el nivel de encapsulación deseado.

+0

Hay muy pocos casos en los que debe hacer esto, como notó Jon. Desafortunadamente tuve que hacerlo más de lo que quisiera admitir, y me da un código MUY desagradable. – aperkins

+0

FAIL. Si elimina la llamada a 'setAccessible', aún funciona, incluso con un administrador de seguridad presente. :) Pero +1 para "normalmente no deberías hacer esto". –

+0

@Tom: Gracias, corrigió el ejemplo a una situación donde * lo * necesita hacer :) –

42

Sí.

Field f = Test.class.getDeclaredField("str"); 
    f.setAccessible(true);//Very important, this allows the setting to work. 
    String value = (String) f.get(object); 

Luego usa el objeto de campo para obtener el valor de una instancia de la clase.

Tenga en cuenta que el método get es a menudo confuso para las personas. Usted tiene el campo, pero no tiene una instancia del objeto. Debe pasarlo al get método

+0

Corto. Sucinto. Pulgares hacia arriba. – Christian

5

Sí, es posible.

Es necesario utilizar el método getDeclaredField (en lugar del método getField), con el nombre de su ámbito privado:

Field privateField = Test.class.getDeclaredField("str"); 

Además, es necesario establecer este campo para ser accesible, si quieres acceder a un campo privado:

privateField.setAccessible(true); 

una vez hecho esto, se puede utilizar el método get en la instancia de campo, para acceder al valor del campo str.

Cuestiones relacionadas