web-dev-qa-db-fra.com

Est-il possible dans Java d'accéder aux champs privés via réflexion

Est-il possible dans Java d'accéder à un champ privé via une réflexion? Par exemple, pour obtenir la valeur de ce champ.

class Test
{
   private String str;
   public void setStr(String value)
   {
      str = value;
   }
}
91
Volodymyr Bezuglyy

Oui, absolument, à condition que vous disposiez des autorisations de sécurité appropriées. Utilisez Field.setAccessible(true) en premier si vous y accédez depuis une autre classe.

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);
    }
}

Et non, vous ne devriez normalement pas faire cela… cela sape les intentions de l'auteur original du cours. Par exemple, une validation peut éventuellement être appliquée dans toute situation où le champ peut normalement être défini, ou d’autres champs peuvent être modifiés en même temps. Vous violez effectivement le niveau d'encapsulation prévu.

178
Jon Skeet

Oui.

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

Ensuite, vous utilisez l'objet de champ pour obtenir la valeur sur une instance de la classe.

Notez que la méthode get est souvent source de confusion pour les gens. Vous avez le champ, mais vous n'avez pas d'instance de l'objet. Vous devez passer cela à la méthode get

51
Yishai

Oui c'est possible.

Vous devez utiliser la méthode getDeclaredField (au lieu de la méthode getField), avec le nom de votre champ privé:

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

De plus, vous devez définir ce champ pour qu'il soit accessible si vous souhaitez accéder à un champ privé:

privateField.setAccessible(true);

Une fois que cela est fait, vous pouvez utiliser la méthode get sur l'instance Field pour accéder à la valeur du champ str.

5
pythonquick