11 juin 2014

Groovy - Différences avec Java


Groovy est un langage qui tourne sur la JVM de Java.

Sa syntaxe se rapproche de Java et cet article liste les différences principales avec Java sans entrer dans les détails des nouvelles fonctionnalités offertes par Groovy. L'objectif est de comprendre du code Groovy quand on connait déjà la syntaxe Java.


Pour développer, il est nécessaire d'installer le SDK de Groovy.

Ce SDK n'est pas nécessaire pour utiliser Gradle qui est un outil de build de projets.

Installation de Groovy

  • Télécharger le fichier ZIP contenant le SDK de Groovy :
  • Décompresser le fichier ZIP pour créer le répertoire d'installation de Groovy
  • Ajouter la variable d'environnement :
    • GROOVY_HOME : le répertoire d'installation de Groovy
  • Ajouter la variable d'environnement au PATH :
    • PATH : ajouter à la fin :
    • ;GROOVY_HOME\bin
      

Langage Groovy : Différences avec Java

Ce chapitre présente les différences majeurs avec le langage Java pour ne pas être perdu :

Fin de ligne

Le point-virgule n'est pas obligatoire en fin de ligne.

Variable

Il est possible de ne pas indiquer le type de la variable : nous utilisons le mot clé def qui indique un typage dynamique de la variable.

Exemple :
String text = "text"
peut s'écrire :
def text = "text"

Les nombres sont de type BigDecimal par défaut lorsque le mot clé def est utilisé pour définir la variable :
def nombre = 3.14
Il est possible de forcer le type d'un nombre : on suffixe le nombre par un des symboles suivants :
  • I : Integer
  • L : Long
  • F : Float
  • D : Double
  • G : BigInteger

Tableau

Contrairement à Java, pour définir un tableau, il faut utiliser les crochets et non les accolades :
def values = [1, 2, 3];

Nous pouvons parcourir un tableau de plusieurs manières, les expressions suivantes sont équivalentes :
for(int i=0; i<values.length; i++) { def value = values[i]; ... }
for(i in 0..values.length-1) { def value = values[i]; ... }
for(i in 0..<values.length) { def value = values[i]; ... }
values.length.times { i -> def value = values[i]; ... }
values.each() { value -> ... }
values.eachWithIndex() { value, i -> ...value... }

Map

Le type par défaut d'une map est java.util.Map.

Voici la syntaxe pour définir une map :
def map = [key1: value1, key2: value2, key3: value3]

Pour définir un tableau vide :
def map = [:]

Nous pouvons parcourir le contenu d'un tableau de la manière suivante :
def values = [1: "Marc", 2: "Steve", 3: "Henri"]

for(def entry in values) { System.out.println(entry.key + " : " + entry.value) }
values.each() { entry -> System.out.println(entry.key + " : " + entry.value) }
values.each() { key, value -> System.out.println(key + " : " + value) }

Classe

Une classe est de visibilité public par défaut.

Il n'est plus obligatoire d'utiliser le mot clé public pour définir une classe.

Il est possible de définir plusieurs classes de visibilité public dans un même fichier .groovy.

Propriétés

Une propriété d'une classe est de visibilité private par défaut.

De plus, les accesseurs getXxx() et setXxx() sont générés par défaut.

Méthode

Une méthode est de visibilité public par défaut.

Le mot clé return est optionnel en Groovy : Groovy retourne alors la dernière expression évaluée.

Cependant si le type de la méthode est void, cette méthode continue à ne retourner aucune valeur. Il faut également que le type de la dernière expression évaluée puisse être converti vers le type retournée par la méthode sinon une exception GroovyCastException est levée.

Exemple :
    public String say() {
        def result = "Hello"
        result += " "
        result + "Max";
    }
La valeur "Hello Max" est retournée par la méthode say().

Imports par défaut

Les packages et classes suivantes sont importés par défaut :
  • java.io.*
  • java.lang.*
  • java.math.BigDecimal
  • java.math.BigInteger
  • java.net.*
  • java.util.*
  • groovy.lang.*
  • groovy.util.*

Test d'égalité ==

Dans Groovy, le signe == correspond à l'utilisation de la méthode equals de l'objet à comparer.

a == b correspond à a.equals(b) mais gère en plus le cas des variables non définies pour éviter les NullPointerException.

Integer a = 1;
BigDecimal b = 1;
a == b // true

a = null
a == b // false => pas de NullPointerException

b = null
a == b // true

Nouvelles fonctionnalités par rapport à Java

  • Closures
  • Syntaxe natives des listes et des maps
  • Support natif des expressions régulières

Exemple

Voici un exemple de code qui mêle du Java et du Groovy :
  • Le fichier Main.java contient la classe Java Main
  • Le fichier Hello.groovy contient deux classes Hello et Max
  • La classe Java Main utilise la classe Groovy Max
Fichier Main.java :
public class Main {
    public static void main(String[] args) {
        Max max = new Max();
        System.out.println(max.say());
    }
}
Fichier Hello.groovy :
class Hello {
    def text = "Hello ! My name is "
    String say(def name) {
        def result = text + " " + name;
    }
}

class Max {
    Hello hello = new Hello();
    String say() {
        hello.say("Max");
    }
}

Références