5.FreshMinutes.IT – Java & IT

5 minutes pour consolider ses connaissances en Java et dans les Nouvelles Technos.
  • Accueil
  • À propos
  • Contact, Twitter, Tumblr & Buzz

Accéder à une variable private dans la classe d’une API avec Reflection

Eric Vialle | Mardi 10 novembre 2009 | 11:25


Voleur accédant a une valeur privéeCertaines API, généralement dont les sources sont fermées ne permettent pas d’accéder à certaines valeurs d’un objet. En effet, dans la définition de leur classe, un champ a été mis à private et aucun getter n’a été mis à disposition. Ce problème m’est arrivé, alors que je développais un solution d’envoie de message par Bluetooth, un objet d’une API d’un développeur tierce contenait dans une variable privée contenant l’adresse MAC d’un utilisateur. Ne pouvant modifier le code source de mon collègue j’ai donc créé une classe respectant les propriété de cette classe tierce, mais permettant d’accéder en plus à ce champ privé.

Je vais ici vous décrire la solution que j’ai développé afin d’accéder à une variable private sans modifier le code source avec la méthode de la Reflection.

Considérons d’abord la classe PrivateDataClass contenant un champ privé dont on ne peut modifier le code source:

  1. /**
  2. * Classe contenant des données privées auxquelles
  3. * nous aimerions avoir accés.
  4. */
  5. public class PrivateDataClass {
  6.     /**
  7.      * Nous n'avons pas accés à myPrivateInt.
  8.      * Mais nous aimerions!
  9.      */
  10.     private int myPrivateInt = 77;
  11.  
  12.     /**
  13.      * Ceci est un exemple de méthode public
  14.      */
  15.     public void myMethod() {
  16.         System.out.println("This is a dummy method");
  17.     }
  18. }

Maintenant nous allons créer la classe héritant des propriétés de PrivateDataClass; PublicDataClass Nous implémenterons une méthode getMyPrivateInt() destinée à récupérer le champ myPrivateInt.

Schéma UML montrant PublicDataAccess permettant de récuperer une variable privée de PrivateDataAccess

Schéma UML montrant PublicDataAccess permettant de récuperer une variable privée de PrivateDataAccess

  1. import java.lang.reflect.Field;
  2.  
  3. /**  Classe étandant une classe avec des champs privées. */
  4. public class PublicDataClass extends PrivateDataClass {
  5.  
  6.     /** On met ici la classe parente dont on hérite les données. */
  7.     private final static Class PARENT_CLASS = PrivateDataClass.class;
  8.  
  9.     /**
  10.      * Permet d'acceder au champs "myPrivateInt"
  11.      * de PrivateDataClass.
  12.      */
  13.     public int getMyPrivateInt() {
  14.         try {
  15.             //1- on recupere la variable privée myPrivateInt de PrivateDataClass
  16.             Field myPrivateField = PARENT_CLASS.getDeclaredField("myPrivateInt");
  17.             //2- On la rend accessible
  18.             myPrivateField.setAccessible(true);
  19.             //3- On recupere l'objet Int
  20.             Integer myObject = (Integer) myPrivateField.get(this);
  21.             //4- L'autoboxing se chargera de le convertir en primitive int
  22.             return myObject;
  23.         } catch (Exception e) {
  24.             e.printStackTrace();
  25.         }
  26.         //Valeur par défaut qui sera jamais atteinte
  27.         return 0;
  28.     }
  29. }

Cette classe peut ensuite être utilisée à la place d’une PrivateDataClass, comme on peut le voir dans ce test de PublicDataClass.

  1. /**
  2. * @author Eric VIALLE
  3. */
  4. public class Main {
  5.  
  6.     /**
  7.      * @param args
  8.      */
  9.     public static void main(String[] args) {
  10.         PublicDataClass publicDataClass = new PublicDataClass();
  11.  
  12.         int value = publicDataClass.getMyPrivateInt();
  13.         System.out.println("Private value: " + value);
  14.  
  15.         //Les autres méthodes de PrivateDataClass
  16.         //sont toujours accessibles
  17.         publicDataClass.myMethod();
  18.  
  19.         //PublicDataClass reste un PrivateDataClass
  20.         //Si un objet de type PrivateDataClass est attendu,
  21.         //On peut lui fournir PublicDataClass
  22.         exemple(publicDataClass);
  23.     }
  24.  
  25.     /**
  26.      * @param monObjet est un PrivateDataClass
  27.      */
  28.     public static void exemple(PrivateDataClass monObjet) {
  29.         System.out.println("PublicDataClass est " +
  30.                 "aussi un PrivateDataClass");
  31.     }
  32. }

Ce Main nous affichera:
Private value: 77
This is a dummy method
PublicDataClass est aussi un PrivateDataClass


Catégories
Dévelopement Tips, J2SE, Java, Tutoriel
Flux rss des commentaires
Flux rss des commentaires
Trackback
Trackback

« Utiliser les services Spring IOC dans des Actions Struts 2.1 avec l’Autocablage (Autowiring) Le nouveau langage Go de Google est il un “Killer Language” ? »

Leave a Reply

Cliquez ici pour annuler la réponse.

Articles récents

  • Push & communications asynchrones sur iOS (iPhone/iPad)
  • Optimiser le temps de chargement pour le web mobile avec iPhone, jQTouch, Struts 2 et Tomcat
  • La philosophie du Domain Driven Design User Group et l’état des lieux * Users Group en Février 2010
  • Introduction au NoSQL (et de Redis) ou le compte rendu du NoSQL User Group Paris de Février 2010
  • Gérer le Cache-Control HTTP dans une application Web Java EE avec Tomcat
  • Compiler son code? “It’s so 2000s” ou un apercu de Play et JRebel
  • Le blog change d’adresse
  • Le Paris JUG a fêté ses 2 ans: compte-rendu

Navigation

  • Actualités Flux pour tous les articles classés dans Actualités
  • Architecture IT Flux pour tous les articles classés dans Architecture IT
  • Base de données Flux pour tous les articles classés dans Base de données
  • Java Flux pour tous les articles classés dans Java
    • Dévelopement Tips Flux pour tous les articles classés dans Dévelopement Tips
    • EDI Flux pour tous les articles classés dans EDI
    • J2ME Flux pour tous les articles classés dans J2ME
    • J2SE Flux pour tous les articles classés dans J2SE
    • Java EE Flux pour tous les articles classés dans Java EE
    • Tutoriel Flux pour tous les articles classés dans Tutoriel
  • Non classé Flux pour tous les articles classés dans Non classé
  • NoSQL Flux pour tous les articles classés dans NoSQL

Promo

Mots Clefs

adobe apache application web Base de données benchmark bugs c# checkstyle dérivation eclipse find bugs findbugs flex framework play google gzip http iPhone jar Java Java User Group java web start JVM microsoft mysql object objet open source optimisation oracle performance plugin pmd polymorphisme qualité recrutement rich internet application serveur silverlight struts struts 2 sun test Tomcat web

WP Cumulus Flash tag cloud by Roy Tanck and Luke Morton requires Flash Player 9 or better.

Twitter

  • J'ai testé OnLive Games sur mon Mac en Wifi: vraiment impressionnant que les possibilités du cloud gaming 2011-01-17
  • More updates...

Livres Pour Aller Plus Loin…

Blogoliste

  • Berthou.com
  • Le blog de hugu
  • PHP – Le Blog de Fatiha
  • techno.blog(java4it)
Get Adobe Flash playerPlugin by wpburn.com wordpress themes
rss Flux rss des commentaires valid xhtml 1.1 design by jide powered by Wordpress get firefox