Blog Zenika

#CodeTheWorld

Java

Groovy 2.0 va vous plaire !

Si vous aimez Java et que vous ne connaissez pas Groovy, je vous invite à découvrir ce langage très addictif !

Présentation de Groovy

En deux mots, Groovy est un langage dynamique, fortement typé qui s’exécute sur la JVM et qui a l’avantage d’avoir une syntaxe très proche de Java et qui propose :

  • une syntaxe plus concise (avec le support natif des listes, des maps, du JSON, du XML, …),
Exemple : def codesPostaux = [ 44000 : "Nantes", 75000 : "Paris" ]
  • un JDK Java enrichi de nouvelles fonctionnalités, qui permet d’écrire le code suivant : voir le Groovy JDK,
Exemple : new File("fichier.txt").eachLine{ line -> println line }
Exemple : use(TimeCategory) { println 1.minute.from.now }
  • permet de modifier le comportement d’une classe ou d’une instance au runtime (via sa métaclasse). Voir définition du monkey-patch,
  • un support du scripting,
  • et plein d’autres choses…

Inconvénients de Groovy 1.8

Malgré tous ses avantages, Groovy, de part son comportement dynamique, concède quelques faiblesses (pour les développeurs Java) :

  • ses performances pures sont moins bonnes que Java (plus significatif sur du calcul que pour des traitements métiers),
  • seule la sémantique est vérifiée à la compilation, pas le code
  • le comportement de votre classe peut être modifié dynamiquement

Groovy 2.0 pour satisfaire tout le monde

Groovy est à l’écoute de la communauté Java et la version 2.0 va certainement plaire à beaucoup de monde.
Pourquoi ?
Tout simplement parce que Groovy 2.0 permettra au développeur de choisir de combler les faiblesses évoquées en activant au niveau d’une classe ou d’une méthode :

La vérification statique de code via l’annotation @TypeChecked

La compilation statique via l’annotation @CompileStatic

Vérification statique
La vérification statique de code ne change pas le comportement de Groovy mais permet de vérifier à la compilation que tous les attributs ou méthodes utilisés sont connues par le compilateur. Cela évite de faire des erreurs du style :

println "hello world".len() //méthode inexistante

Bien évidemment, si vous avez besoin du comportement dynamique, il ne faudra pas ajouter l’annotation.
Compilation statique
La compilation statique quant à elle désactive toutes les fonctionnalités dynamique de Groovy et produit du bytecode Java plus « standard » (appel de méthode directe, …). Les impacts directs sont des gains de performances (du niveau de Java) et des erreurs détectées à la compilation (plus stricte encore que lors de la vérification statique).
Cette fonctionnalité est en cours de développement et certains choix d’implémentation reste encore à faire, principalement au niveau des appels de méthodes.
Pour présenter le dilemme, prenons le code suivant :

def foo(Object o){ println 'object' }
def foo(Date d){ println 'date' }
Object date = new Date()
foo(date)

En Java, l’exécution de ce code affiche object car le lien vers la méthode est fait à la compilation à partir du type déclaré de l’attribut date. C’est d’ailleurs une erreur que l’on fait souvent en tant que développeur Java. On pense que la bonne méthode sera appelée, … et non ! En groovy, le compilateur est un peu plus intelligent et sait que le type de l’attribut date est java.util.Date. Selon le code, il est possible que le compilateur Groovy ne puisse pas déterminer le type d’une variable. C’est pourquoi, le comportement standard de Groovy est de résoudre le type au runtime pour appeler la méthode la plus adéquate.
La question qui se pose est donc : « Le lien vers la méthode doit-il se faire » :

  • A partir du type déclaré, comme en Java,
  • A partir du type inféré par le compilateur Groovy.
  • A partir du type exact au runtime.

L’idéal est sûrement la dernière solution, mais ce serait forcément moins « statique », car il faudrait analyser le type de la variable pendant l’exécution puis faire un appel par réflexivité … et adieu aux perfs.
En tant que développeur, avec Java, soit on est conscient du comportement, et il faut ajouter les (Cast) explicitement pour avoir ce comportement, soit on ne sait pas et l’exécution du code n’est pas toujours celui attendu.
Je me dis donc que si groovy peut en faire une partie, autant le prendre. Donc je pencherai pour la solution 2, mais quoi qu’il en soit, l’important est de connaître la règle.
D’ailleurs, même en Java, il y a plein de « corner case » que peu de développeur connaissent. Par exemple, d’après vous, que ce passe t’il si on exécute ce code :

class Base {
    public  String name = "Base";
    public  String getName() { return name; }
}
class Sub extends Base {
    public String name = "Sub";
    public String getName() { return name; }
}
public class Program {
    public static void main(String[] args) {
        Sub s  = new Sub();
        Base b = s;
        System.out.println(b.name);
    }
}

Pour finir sur le choix à propos de l’appel de méthode, pour ceux qui préfèrent le comportement Groovy, il est toujours possible de ne pas activer la compilation statique, ou bien d’ajouter le (Cast) pour avoir ce comportement :

def foo(Object o){
    if (foo instanceof Date){
        foo((Date)o)
    } else {
        println 'object'
    }
}

Et vous, quel est votre avis ? N’hésitez pas à le donner en ajoutant un commentaire à cet article.

Utilisez Groovy comme il vous semble

En résumé, Groovy 2.0 essaye de combler certaines frustrations exprimées par la communauté Java, sans pour autant changer sa philosophie. Groovy reste un langage dynamique, mais permet de désactiver certaines de ces fonctionnalités si vous n’en n’avez pas besoin, pour gagner au niveau de la vérification du code et en performance.
Si vous voulez en savoir plus sur ces fonctionnalités, je vous invite à lire la très bonne présentation de Cédric Champeau de vmware que vous trouverez à cette adresse.
Vous trouverez également plus de documentation sur le site des GEP (Groovy Enhancement Proposal) et sur le blog de Cédric.
Je n’ai pas parlé de l’utilisation de invokeDynamic au niveau du bytecode Groovy qui est aussi une des features proposées pour les utilisateurs de Java7, mais vous pouvez trouver plus d’info sur cette page du site de Groovy
D’ailleurs, si vous souhaitez tester ces fonctionnalités et faire avancer Groovy, vous pouvez télécharger la version 2.0 beta sur le site de Groovy, et pour la compilation statique, qui est présent à partir de la béta 3, vous devez télécharger la version snapshot ici en attendant la version béta.
J’espère vous avoir donné envie d’essayer Groovy !
Manuel
Télécharger la béta de Groovy (pour la compilation statique ;..)

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

En savoir plus sur Blog Zenika

Abonnez-vous pour poursuivre la lecture et avoir accès à l’ensemble des archives.

Continue reading