![]() |
Introspection |
Soit la classe suivante, représentant des graphes orientés avec un nœud initial :
public class Graph { private Node start; public void setStart(Node n) { start = n; } public class Node { private final String name; private final ArrayList<Node> transitions = new ArrayList<Node>(); public Node(String name) { this.name=name; } public int hashCode() { return name.hashCode(); } public boolean equals(Object o) { if (!(o instanceof Node)) return false; return name.equals(((Node)o).name); } public void add(Node dest) { transitions.add(dest); } public Iterator<Node> transitions() { return transitions.iterator(); } public String toString() { return name; } } }
toString()
dans la classe
Graph
. L'affichage indique le nœud initial,
puis une ligne par nœud du graphe, chaque ligne affichant
le nœud suivi de deux points et des nœuds vers
lesquels il possède un arc. L'affichage de chaque nœud
comprend un identificateur du nœud et le nom du nœud
entre parenthèses. Par exemple, voici un graphe et l'affichage
souhaité :
![]() |
Noeud initial: n1(Bleu) n1(Bleu) : n2(Rouge) n3(Rouge) n2(Rouge) : n4(Vert) n3(Rouge) : n4(Vert) n4(Vert) : n1(Bleu) n5(Bleu) n5(Bleu) : n5(Bleu) |
Les itérateurs obtenus à partir des collections du paquetage
java.util
sont dits fail-fast, ce qui
signifie qu'une modification de la structure itérée entrelacée avec
l'utilisation de l'itérateur provoque par cette dernière la levée
d'une ConcurrentModificationException
. Pour contrôler
ces modifications, les itérateurs utilisent le champ
modCount
protégé de la classe abstraite
AbstractList
. Pour vous en convaincre, vous pouvez
extraire le code source de ces classes de l'archive
src.zip
.
En utilisant les mécanismes de réflexion offerts par le paquetage
java.lang.reflect
, écrire une méthode
bidouille()
et faites en sorte que, dans le cas
particulier l'exemple suivant, l'exception
ConcurrentModificationException
ne soit pas levée par
l'itérateur d'un ArrayList
, malgré la modification faite
sur cette structure. Pour celà, vous devrez modifier par réflexion la
valeur du champ modCount
de la liste.
ArrayList<String> list = new ArrayList<String>(); Collections.addAll(list,args); for(String s:list) { if (s.length()%2==0) { list.add(s+" stop"); // bidouille(list); à écrire... } } System.out.println(list);
On souhaite maintenant avoir un algorithme qui affiche
n'importe quel Object
au format XML suivant :
<instance class="java.awt.Point" id="1"> <field name="x" value="10"> <field name="y" value="20"> </instance>ou pour les nœuds du graphe, quelque chose dans ce genre :
<instance class="Graphe" id="1"> <field name="start" id-ref="2"> </instance> <instance class="Graph.Node" id="2"> <field name="name" value="root"> <field name="transitions" id-ref="3"> </instance> <instance class="java.util.ArrayList" id="3"> <field name="modCount" value="3"> <field name="size" value="2"> <field name="elementData" id-ref="4"> </instance> <instance class="java.lang.Object[]" id="4"> <field name="length" value="11"> <field id-ref="5"> <field id-ref="6"> </instance> <instance class="Graph.Node" id="5"> <field name="name" value="node1"> <field name="transitions" id-ref="7"> </instance> ...Vous veillerez à sauver les champs de type primitif et
String
suivant leurs valeurs, les objets sous la
forme de leur référence d'identifiant et les tableaux d'une façon
spéciale.