Bonjour à tous,
Je me suis récemment confronté à un petit problème en Java. Effectivement je suis en train de développer un programme où l'on me demande à chaque fois que je fais appel à une méthode d'afficher dans les logs toutes les variables du ou des objets en entrée de la méthode ainsi que toutes les variables de l'objet en sortie. Sachant que certain de ces objets ont parfois jusqu'à 50 variables faire des .get() à la chaîne n'est évidemment pas une solution d'autant plus que si l'objet évolue la log devient obsolète.
Bon là normalement vous allez me dire "Mais rien de plus simple, tu n'as qu'à surenchérir la méthode toString dans tes objets !", oui je serais d'accord avec vous, mais voilà il y a un hic. Ces objets sont générés via un outil de modélisation et il est interdit de les retoucher à la main derrière :/
J'ai donc eu une idée, créer une méthode grâce à la réflexivité et la récursivité qui créerait un String à la volée avec toutes les variables de l'objet en entrée de la méthode. J'ai commencé à travailler sur cette piste et voici la méthode telle que je la vois pour le moment :
En l'état, cette méthode "fonctionne", on peut obtenir un String un résultat qui a cette tête là :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 public static String objectToString(Object obj) throws IllegalArgumentException, IllegalAccessException { String toString = "["; boolean fistField = true; Field[] fields = obj.getClass().getDeclaredFields(); //on parcourt tous les champs de l'objet for (Field field : fields) { //on rend accessible le champ pour récupérer sa valeur field.setAccessible(true); //Si ce n'est pas le premier objet on rajoute une virgule if(!fistField) { toString = toString + ", "; } //Si le type de la variable du champ n'est ni une primitive, ni un enum //et que la longueur son nom est plus petit que 10 ou égal et supérieur à 10 //mais que son début n'est pas églale à "class java" afin d'éviter les classes de Type HashMap, ArrayList, ect... if (!field.getType().isPrimitive() && !field.getType().isEnum() && (field.getType().toString().length() < 10 || field.getType().toString().length() >= 10 && !field.getType().toString().substring(0, 10).equals("class java"))) { //alors c'est que c'est un Objet //on peut donc faire appel à cette méthode de manière récursive //on rapelle donc cette méthode afin de récupérer les valeurs des champs de l'objet toString = toString + field.getName() + "=" +objectToString(field.get(obj)); } else { toString = toString + field.getName() + "=" + field.get(obj); } //on rend de nouveau non accessible le champ field.setAccessible(false); fistField = false; } toString = toString + "]"; return toString; }
Ça fonctionne donc avec les types primitifs, les objets (grâce à la récursivité), les listes, les map, les enums et les objets de primitives (Double, Integer, BigDecimal, etc...). Seulement comme vous pouvez le voir dans le code, cela fonctionne, mais je l'ai fait un peu de manière "Brutal", en tout cas ça ne me plait pas vraiment en l'état.
Code : Sélectionner tout - Visualiser dans une fenêtre à part Objet1: [variableIntObj1=1, variableStringObj1=test, variableHashMapObj1={variableStringList1=123, variableStringList2=456}, Objet2=[variableDoubleObj2=123.0, variableFloatObj2=12.123], variableEnumObj1=TATA, variableBigIntegerObj1=11]
Pour cause cette ligne de code dans mon if :
Je fais cela en fait pour tester que l'objet que je teste ne soit pas un objet du package java et donc que l'objet ne soit pas une liste, collection, ou objet de primitive afin de ne pas utiliser la récursivité dessus. Cette façon de façon de faire à des limites et elle n'est pas élégante, par exemple si j'ai une liste d'objet et bien je ne vais pas afficher leurs variables, mais l'adresse de l'objet.
Code : Sélectionner tout - Visualiser dans une fenêtre à part !field.getType().toString().substring(0, 10).equals("class java")
Donc y a-t-il une manière de "mieux" faire ? Ou alors est-ce que je me complique trop la vie et il y a une manière beaucoup plus simple de faire ce que je souhaite ?
Merci d'avance pour vos réponses![]()
Partager