Qu'est-ce que la réflexion et pourquoi est-elle utile?
Je suis particulièrement intéressé par Java, mais je suppose que les principes sont les mêmes dans tous les langages.
java
reflection
terminology
Lehane
la source
la source
@Jailbreak
. Il fournit un accès direct et sécurisé aux champs, méthodes, etc. privés. Laissez le compilateur Java vérifier en toute sécurité votre code et laissez Manifold générer l'accès de réflexion sous-jacent pour vous. En savoir plus: manifold.systems/docs.html#type-safe-reflectionRéponses:
La réflexion du nom est utilisée pour décrire le code qui est capable d'inspecter un autre code dans le même système (ou lui-même).
Par exemple, supposons que vous ayez un objet de type inconnu en Java et que vous souhaitiez appeler une méthode 'doSomething' s'il existe. Le système de typage statique de Java n'est pas vraiment conçu pour prendre en charge cela à moins que l'objet ne soit conforme à une interface connue, mais en utilisant la réflexion, votre code peut regarder l'objet et savoir s'il a une méthode appelée 'doSomething' puis l'appeler si vous vouloir.
Donc, pour vous donner un exemple de code en Java (imaginez que l'objet en question est foo):
Un cas d'utilisation très courant en Java est l'utilisation d'annotations. JUnit 4, par exemple, utilisera la réflexion pour rechercher dans vos classes les méthodes marquées de l'annotation @Test, puis les appellera lors de l'exécution du test unitaire.
Il existe de bons exemples de réflexion pour vous aider à démarrer sur http://docs.oracle.com/javase/tutorial/reflect/index.html
Et enfin, oui, les concepts sont à peu près similaires dans d'autres langages typés statiquement qui prennent en charge la réflexion (comme C #). Dans les langages typés dynamiquement, le cas d'utilisation décrit ci-dessus est moins nécessaire (puisque le compilateur permettra à n'importe quelle méthode d'être appelée sur n'importe quel objet, échouant à l'exécution si elle n'existe pas), mais le deuxième cas de recherche de méthodes qui sont marquées ou le travail d'une certaine manière est encore courant.
Mise à jour à partir d'un commentaire:
la source
Method
,Constructor
,Modifier
,Field
,Member
, à l' exception essentiellement apparemment tousClass
) sont dans lejava.lang.*reflect*
paquet. Peut-être que le concept de «réflexion» comprend à la fois «introspection de type» et modification au moment de l'exécution?Par exemple, tous les objets en Java ont la méthode
getClass()
, qui vous permet de déterminer la classe de l'objet même si vous ne le connaissez pas au moment de la compilation (par exemple si vous l'avez déclaré comme unObject
) - cela peut sembler trivial, mais une telle réflexion n'est pas possible dans des langues moins dynamiques commeC++
. Des utilisations plus avancées vous permettent de répertorier et d'appeler des méthodes, des constructeurs, etc.La réflexion est importante car elle vous permet d'écrire des programmes qui n'ont pas à "tout savoir" au moment de la compilation, ce qui les rend plus dynamiques, car ils peuvent être liés ensemble au moment de l'exécution. Le code peut être écrit sur des interfaces connues, mais les classes réelles à utiliser peuvent être instanciées en utilisant la réflexion des fichiers de configuration.
De nombreux cadres modernes utilisent largement la réflexion pour cette même raison. La plupart des autres langages modernes utilisent également la réflexion et, dans les langages de script (tels que Python), ils sont encore plus étroitement intégrés, car cela semble plus naturel dans le modèle de programmation général de ces langages.
la source
C++
possède des informations sur le type d'exécution. RTTIL'une de mes utilisations préférées de la réflexion est la méthode de vidage Java ci-dessous. Il prend n'importe quel objet comme paramètre et utilise l'API de réflexion Java pour imprimer chaque nom et valeur de champ.
la source
callCount
doit être défini sur zéro. Sa valeur est utilisée pour déterminer combien d'onglets doivent précéder chaque ligne de sortie: chaque fois que le vidage doit vider un "sous-objet", la sortie s'imprime telle qu'elle est imbriquée dans le parent. Cette méthode s'avère utile lorsqu'elle est enveloppée dans une autre. ConsidérezprintDump(Object obj){ System.out.println(dump(obj, 0)); }
.Utilisations de la réflexion
La réflexion est couramment utilisée par les programmes qui nécessitent la possibilité d'examiner ou de modifier le comportement d'exécution des applications s'exécutant dans la machine virtuelle Java. Il s'agit d'une fonctionnalité relativement avancée et ne doit être utilisée que par des développeurs qui ont une bonne compréhension des principes fondamentaux du langage. Avec cette mise en garde à l'esprit, la réflexion est une technique puissante et peut permettre aux applications d'effectuer des opérations qui seraient autrement impossibles.
Fonctions d'extensibilité
Une application peut utiliser des classes externes définies par l'utilisateur en créant des instances d'objets d'extensibilité en utilisant leurs noms complets. Navigateurs de classe et environnements de développement visuel Un navigateur de classe doit pouvoir énumérer les membres des classes. Les environnements de développement visuel peuvent bénéficier de l'utilisation des informations de type disponibles en réflexion pour aider le développeur à écrire le code correct. Débogueurs et outils de test Les débogueurs doivent pouvoir examiner les membres privés dans les classes. Les faisceaux de tests peuvent utiliser la réflexion pour appeler systématiquement un ensemble détectable d'API définies sur une classe, afin d'assurer un niveau élevé de couverture de code dans une suite de tests.
Inconvénients de la réflexion
La réflexion est puissante, mais ne doit pas être utilisée sans discernement. S'il est possible d'effectuer une opération sans utiliser de réflexion, il est préférable d'éviter de l'utiliser. Les préoccupations suivantes doivent être gardées à l'esprit lors de l'accès au code via la réflexion.
La réflexion impliquant des types résolus dynamiquement, certaines optimisations de machine virtuelle Java ne peuvent pas être effectuées. Par conséquent, les opérations réfléchissantes ont des performances plus lentes que leurs homologues non réfléchissantes et doivent être évitées dans les sections de code qui sont fréquemment appelées dans les applications sensibles aux performances.
Reflection nécessite une autorisation d'exécution qui peut ne pas être présente lors de l'exécution sous un gestionnaire de sécurité. C'est dans une considération importante pour le code qui doit s'exécuter dans un contexte de sécurité restreint, comme dans une applet.
Étant donné que la réflexion permet au code d'effectuer des opérations qui seraient illégales dans le code non réfléchissant, telles que l'accès aux champs et méthodes privés, l'utilisation de la réflexion peut entraîner des effets secondaires inattendus, qui peuvent rendre le code dysfonctionnel et détruire la portabilité. Le code réfléchissant rompt les abstractions et peut donc changer de comportement avec les mises à niveau de la plateforme.
source: l' API Reflection
la source
La réflexion est un mécanisme clé pour permettre à une application ou un framework de fonctionner avec du code qui n'a peut-être même pas encore été écrit!
Prenez par exemple votre fichier web.xml typique. Celui-ci contiendra une liste d'éléments de servlet, qui contiennent des éléments imbriqués de classe de servlet. Le conteneur de servlet traitera le fichier web.xml et créera une nouvelle instance de chaque classe de servlet par réflexion.
Un autre exemple serait l'API Java pour l'analyse XML (JAXP) . Où un fournisseur d'analyseur XML est «branché» via des propriétés système bien connues, qui sont utilisées pour construire de nouvelles instances par réflexion.
Et enfin, l'exemple le plus complet est Spring qui utilise la réflexion pour créer ses beans, et pour son utilisation intensive de proxy
la source
Toutes les langues ne prennent pas en charge la réflexion, mais les principes sont généralement les mêmes dans les langues qui la soutiennent.
La réflexion est la capacité de «réfléchir» sur la structure de votre programme. Ou plus concret. Pour consulter les objets et les classes dont vous disposez et récupérer par programmation des informations sur les méthodes, les champs et les interfaces qu'ils implémentent. Vous pouvez également consulter des éléments tels que les annotations.
C'est utile dans beaucoup de situations. Partout où vous voulez pouvoir brancher dynamiquement des classes dans votre code. De nombreux mappeurs relationnels d'objets utilisent la réflexion pour pouvoir instancier des objets à partir de bases de données sans savoir à l'avance quels objets ils vont utiliser. Les architectures plug-in sont un autre endroit où la réflexion est utile. Être capable de charger dynamiquement du code et de déterminer s'il existe des types qui implémentent la bonne interface à utiliser en tant que plugin est important dans ces situations.
la source
La réflexion permet l'instanciation de nouveaux objets, l'invocation de méthodes et les opérations get / set sur les variables de classe dynamiquement au moment de l'exécution sans avoir une connaissance préalable de son implémentation.
Dans l'exemple ci-dessus, le paramètre null est l'objet sur lequel vous souhaitez appeler la méthode. Si la méthode est statique, vous fournissez null. Si la méthode n'est pas statique, alors lors de l'appel, vous devez fournir une instance MyObject valide au lieu de null.
La réflexion vous permet également d'accéder aux membres / méthodes privés d'une classe:
.
java.lang.reflect
). Les métadonnées de classe sont accessibles viajava.lang.Class
.Reflection est une API très puissante mais elle peut ralentir l'application si elle est utilisée en excès, car elle résout tous les types lors de l'exécution.
la source
Java Reflection est assez puissant et peut être très utile. Java Reflection permet d'inspecter les classes, les interfaces, les champs et les méthodes lors de l'exécution, sans connaître les noms des classes, méthodes, etc. au moment de la compilation. Il est également possible d' instancier de nouveaux objets, d'appeler des méthodes et d'obtenir / définir des valeurs de champ à l'aide de la réflexion.
Un exemple rapide de réflexion Java pour vous montrer à quoi ressemble la réflexion:
Cet exemple obtient l'objet Class de la classe appelée MyObject. En utilisant l'objet class, l'exemple obtient une liste des méthodes de cette classe, itère les méthodes et imprime leurs noms.
Exactement comment tout cela fonctionne est expliqué ici
Edit : Après presque 1 an, je modifie cette réponse car en lisant sur la réflexion, j'ai eu peu d'autres utilisations de la réflexion.
Lorsque le contexte Spring traite cet élément <bean>, il utilise Class.forName (String) avec l'argument "com.example.Foo" pour instancier cette classe.
Il utilisera ensuite à nouveau la réflexion pour obtenir le setter approprié pour l'élément <property> et définir sa valeur sur la valeur spécifiée.
Pour les méthodes privées,
Pour les champs privés,
la source
Exemple:
Prenons par exemple une application distante qui donne à votre application un objet que vous obtenez en utilisant leurs méthodes API. Maintenant, en fonction de l'objet, vous devrez peut-être effectuer une sorte de calcul.
Le fournisseur garantit que l'objet peut être de 3 types et nous devons effectuer un calcul en fonction de ce type d'objet.
Nous pouvons donc implémenter dans 3 classes contenant chacune une logique différente. Évidemment, les informations sur l'objet sont disponibles au moment de l'exécution, vous ne pouvez donc pas coder statiquement pour effectuer le calcul, donc la réflexion est utilisée pour instancier l'objet de la classe dont vous avez besoin pour effectuer le calcul en fonction de la objet reçu du fournisseur.
la source
instanceof
pour déterminer le type d'objet lors de l'exécution?Exemple simple de réflexion. Dans une partie d'échecs, vous ne savez pas ce qui sera déplacé par l'utilisateur au moment de l'exécution. la réflexion peut être utilisée pour appeler des méthodes déjà implémentées au moment de l'exécution:
la source
Reflection est une API utilisée pour examiner ou modifier le comportement des méthodes, des classes et des interfaces lors de l'exécution.
java.lang.reflect package
.Les packages
java.lang
etjava.lang.reflect
fournissent des classes pour la réflexion Java.La réflexion peut être utilisée pour obtenir des informations sur -
Classe La
getClass()
méthode est utilisée pour obtenir le nom de la classe à laquelle appartient un objet.Constructeurs La
getConstructors()
méthode est utilisée pour obtenir les constructeurs publics de la classe à laquelle appartient un objet.Méthodes La
getMethods()
méthode est utilisée pour obtenir les méthodes publiques de la classe à laquelle appartient un objet.L' API Reflection est principalement utilisée dans:
IDE (Integrated Development Environment), par exemple Eclipse, MyEclipse, NetBeans, etc.
Débogueur et outils de test, etc.
Avantages de l'utilisation de la réflexion:
Fonctions d'extensibilité: une application peut utiliser des classes externes définies par l'utilisateur en créant des instances d'objets d'extensibilité à l'aide de leurs noms complets.
Outils de débogage et de test: les débogueurs utilisent la propriété de réflexion pour examiner les membres privés des classes.
Désavantages:
Surcharge des performances: les opérations réfléchissantes ont des performances plus lentes que leurs homologues non réfléchissantes et doivent être évitées dans les sections de code qui sont fréquemment appelées dans les applications sensibles aux performances.
Exposition des internes: le code réfléchissant rompt les abstractions et peut donc modifier le comportement avec les mises à niveau de la plate-forme.
Réf: Java Reflection javarevisited.blogspot.in
la source
Selon ma compréhension:
La réflexion permet au programmeur d'accéder dynamiquement aux entités du programme. c'est-à-dire tout en codant une application si le programmeur n'est pas au courant d'une classe ou de ses méthodes, il peut utiliser cette classe dynamiquement (au moment de l'exécution) en utilisant la réflexion.
Il est fréquemment utilisé dans les scénarios où un nom de classe change fréquemment. Si une telle situation se produit, il est alors compliqué pour le programmeur de réécrire l'application et de changer encore et encore le nom de la classe.
Au lieu de cela, en utilisant la réflexion, il est nécessaire de s'inquiéter d'un éventuel changement de nom de classe.
la source
La réflexion est un ensemble de fonctions qui vous permet d'accéder aux informations d'exécution de votre programme et de modifier son comportement (avec certaines limitations).
Il est utile car il vous permet de modifier le comportement d'exécution en fonction des métadonnées de votre programme, c'est-à-dire que vous pouvez vérifier le type de retour d'une fonction et changer la façon dont vous gérez la situation.
En C # par exemple, vous pouvez charger un assembly (un .dll) en runtime et l'examiner, en parcourant les classes et en prenant des actions en fonction de ce que vous avez trouvé. Il vous permet également de créer une instance d'une classe lors de l'exécution, d'appeler sa méthode, etc.
Où peut-il être utile? N'est pas utile à chaque fois, mais pour des situations concrètes. Par exemple, vous pouvez l'utiliser pour obtenir le nom de la classe à des fins de journalisation, pour créer dynamiquement des gestionnaires d'événements en fonction de ce qui est spécifié dans un fichier de configuration, etc.
la source
Je veux juste ajouter quelque chose à tout ce qui était répertorié.
Avec l' API Reflection, vous pouvez écrire une
toString()
méthode universelle pour n'importe quel objet.Il est utile lors du débogage.
Voici un exemple:
la source
La réflexion consiste à laisser un objet voir son apparence. Cet argument ne semble pas lié à la réflexion. En fait, c'est la capacité "d'auto-identification".
La réflexion elle-même est un mot pour ces langages qui manquent de capacité de connaissance de soi et d'auto-détection comme Java et C #. Parce qu'ils n'ont pas la capacité de se connaître, quand nous voulons observer à quoi ça ressemble, nous devons avoir une autre chose pour réfléchir à quoi ça ressemble. D'excellents langages dynamiques tels que Ruby et Python peuvent percevoir la réflexion de leur propre sans l'aide d'autres individus. Nous pouvons dire que l'objet de Java ne peut pas percevoir à quoi il ressemble sans miroir, qui est un objet de la classe de réflexion, mais un objet en Python peut le percevoir sans miroir. C'est pourquoi nous avons besoin d'une réflexion en Java.
la source
Depuis la page de documentation java
AccessibleObject
permet la suppression des contrôles d'accès si le nécessaireReflectPermission
est disponible.Les classes de ce package, ainsi que
java.lang.Class
les applications adaptées telles que les débogueurs, les interprètes, les inspecteurs d'objets, les navigateurs de classe et les services tels queObject Serialization
etJavaBeans
qui ont besoin d'accéder aux membres publics d'un objet cible (en fonction de sa classe d'exécution) ou aux membres déclarés par une classe donnéeIl comprend les fonctionnalités suivantes.
Jetez un œil à ce lien de documentation pour les méthodes exposées par
Class
classe.De cet article (par Dennis Sosnoski, président, Sosnoski Software Solutions, Inc) et de cet article (explorations de sécurité en pdf):
Je peux voir des inconvénients considérables par rapport à l'utilisation de Reflection
Utilisateur de la réflexion:
Inconvénients de la réflexion:
Abus généraux:
Jetez un oeil à cette question SE concernant la fonctionnalité d'abus de réflexion:
Comment lire un champ privé en Java?
Sommaire:
L'utilisation non sécurisée de ses fonctions à partir d'un code système peut également facilement conduire à la compromission d'un mode de sécurité Java l. Utilisez donc cette fonctionnalité avec parcimonie
la source
Woozle
examiner d'autres classes au démarrage pour voir lesquelles ont uneRegisterAsWoozleHelper()
méthode statique et d'appeler toutes ces méthodes qu'elle trouve avec un rappel qu'elles peuvent utiliser pour se raconterWoozle
, en évitant besoin d'utiliser Reflection tout en désérialisant par exemple les données.Comme son nom l'indique, il reflète ce qu'il contient, par exemple la méthode de classe, etc., en plus de fournir une fonctionnalité pour appeler la méthode créant une instance dynamiquement au moment de l'exécution.
Il est utilisé par de nombreux frameworks et applications sous le bois pour appeler des services sans vraiment connaître le code.
la source
La réflexion vous donne la possibilité d'écrire du code plus générique. Il vous permet de créer un objet lors de l'exécution et d'appeler sa méthode lors de l'exécution. Par conséquent, le programme peut être rendu hautement paramétré. Il permet également d'introspectionner l'objet et la classe pour détecter ses variables et sa méthode exposées au monde extérieur.
la source
Reflection
a de nombreuses utilisations . Celui que je connais le mieux, c'est de pouvoir créer du code à la volée.la source
Je veux répondre à cette question par l'exemple. Tout d'abord, le
Hibernate
projet utiliseReflection API
pour générer desCRUD
instructions pour combler le gouffre entre l'application en cours d'exécution et le magasin de persistance. Lorsque les choses changent dans le domaine, leHibernate
doit les connaître pour les conserver dans le magasin de données et vice versa.Fonctionne également
Lombok Project
. Il injecte simplement du code au moment de la compilation, ce qui entraîne l'insertion de code dans vos classes de domaine. (Je pense que c'est OK pour les getters et les setters)Hibernate
choisireflection
car il a un impact minimal sur le processus de génération d'une application.Et à partir de Java 7, nous avons
MethodHandles
, qui fonctionne commeReflection API
. Dans les projets, pour travailler avec les enregistreurs, il suffit de copier-coller le code suivant:Parce qu'il est difficile de faire une faute de frappe dans ce cas.
la source
Comme je trouve préférable de l'expliquer par l'exemple et aucune des réponses ne semble le faire ...
Un exemple pratique d'utilisation des réflexions serait un serveur de langage Java écrit en Java ou un serveur de langage PHP écrit en PHP, etc. Afin d'avoir tous les noms de balises (mots qui peuvent être remplis automatiquement) pour afficher toutes les correspondances possibles lors de la frappe, le serveur de langue doit inspecter tout ce qui concerne la classe, y compris les blocs doc et les membres privés. Pour cela, il a besoin d'un reflet de ladite classe.
Un autre exemple serait un test unitaire d'une méthode privée. Une façon de le faire est de créer une réflexion et de changer la portée de la méthode au public dans la phase de configuration du test. Bien sûr, on peut affirmer que les méthodes privées ne doivent pas être testées directement, mais ce n'est pas le but.
la source