:: Enseignements :: Master :: M1 :: 2007-2008 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Quelques notes pour le TD8 |
Reflection
-
Une instance de la classe
Class
représente une classe particulière; Cette instance est
unique pour une classe donnée. L'instance permet de
faire de l'introspection : on peut demander pendant
l'exécution de programmes
-
les champs, les constructeurs et les méthodes de
la classe, représentés par des instances de
classes de
java.lang.reflect
;
-
avec ces instances, on peut créer des objets,
affecter des champs et appeler des méthodes.
-
Pour obtenir des objets
Class
,
-
la construction
NomDeClasse.class
permet d’obtenir l’objet
Class
associé à la classe
NomDeClasse
.
-
la méthode
getClass()
de
Object
permet de connaître le type (réel) d’un objet ;
-
la méthode statique
forName
de la classe
Class
permet d’obtenir un objet
Class
à partir du nom complet de la classe;
-
A partir d'une classe ont peux accéder à l'ensemble de
ces membres :
-
les constructeurs d'objets de type T sont
représentés par des instances de la classe
Constructor<T>
.
-
les champs sont représentés par des instances de
la classe
Field
;
-
les méthodes sont représentées par des instances
de la classe
Method
;
-
les classes internes sont représentées par des
instances de la classe
Class
;
-
Avec
XXX, Constructor, Field, Method
ou
Class
:
-
la méthode
getDeclaredXXXs()
, qui renvoie tous les XXX (privés inclus) qui
sont déclarés par la classe, c'est-à-dire non
hérités ;
-
la méthode
getXXXs()
, qui retourne tous les XXX publics, y-compris
ceux qui sont hérités.
-
la méthode
getDeclaredXXX(param)
, qui renvoie le XXX déclaré, dont le nom et/ou
le type des paramètres est donné en argument ;
-
la méthode
getXXX(param)
, qui retourne le XXX public, hérité ou non,
dont le nom et/ou les types (objets
Class
) des paramètres sont donnés en argument ;
Annotation
-
Pour Java, une annotation est lors de sa déclaration,
une interface; pour son utilisation, une classe
implantant l'interface.
-
Une annotation se déclare comme une interface, mais avec
@interface
.
-
Chaque paramètre de l'annotation est une méthode sans
argument, dont le type de retour doit être valide.
-
On peut fournir un argument par défaut avec le mot-clef
default
.
-
La méthode par défaut est
value()
.
Annotation et Reflection
-
Les élements annotables implantent
AnnotedElement
-
Une annotation d'un certain type est présente se teste
avec
boolean isAnnotationPresent(Class<? extends
Annotation> annotationClass)
-
Demande une annotation spécifique (ou null):
<T extends Annotation> T
getAnnotation(Class<T> annotationClass)
-
Demande les annotations déclarées:
Annotation[] getDeclaredAnnotations()
-
Demande toutes les annotations (
@Inherit
):
Annotation[] getAnnotations()
-
En fonction de la méta-annotations
@Retention
les annotations sont disponibles :
-
RetentionPolicy.SOURCE
, l'annotation n'est vu que par le compilateur
ou par un parser d'annotation
-
RetentionPolicy.CLASS
, l'annotation est vu par le compilateur et par
le chargeur de classe
-
RetentionPolicy.RUNTIME
, l'annotationest vu par le compilateur, par le
chargeur de classe et par reflexion
-
On récupère les annotations à runtime par reflexion, à
partir de l'élement correspondant (
Class, Field, Method
, etc).
java.lang.reflect et Sécurité
-
Par défaut, la reflexion vérifie la sécurité lors de
l'exécution, on ne peut alors effectuer les opérations
que si l'on a les droits
-
Les
Constructor, Field
et
Method
héritent de
AccessibleObject
qui possède un méthode
setAccessible
qui permet d'éviter de faire le test de sécurité (i.e.
de passer outre la sécurité et d'accélerer le code).
-
On peut alors appelé des méthodes privées, changer la
valeur d'un champs final ...
java.lang.ClassLoader
-
Object utilisé pour charger dynamiquement les classes
Java lorsque celles-ci sont demandées
-
Le classloader possède une méthode
loadClass()
qui permet de chargée une classe par son nom (avec le
paquetage) : si la classe n'est pas trouvée une
exception
ClassNotFoundException
est levée
-
La classe est chargée mais pas forcément initialisée
-
Chaque classe connait son classloader que l'on peut
obtenir avec la méthode
class.getClassLoader()
-
Si la classe est chargée par le classloader primordiale,
getClassLoader()
renvoie
null
-
Un classloader possède un parent (
getParent()
)
-
Le mécanisme des classloaders oblige (normalement) un
classloader à demander à son parent s'il ne peut pas
charger une classe avant d'essayer de la chargée
lui-même.
-
Les méthodes de chargement des classes peuvent (1)
charger la classe en demandant au père d'abord (
loadClass(String name)
) ou (2) charger une classe localement (
findClass(String name)
)
© Université de Marne-la-Vallée