Die Sprache Groovy kann mit Java fast eins zu eins interagieren. Durch ihre optionale statische Typisierung und ihre dynamischen Features bis hin zu Closures ist sie ein interessanter Kandidat, um mit funktionaler Programmierung in Berührung zu kommen – ohne sich syntaktisch zu weit von Java zu entfernen.
Artikelserie
Teil 1: Clojure
Teil 2: Scala
Teil 3: Groovy
Teil 4: Jython
Im TIOBE Index rangierte Groovy auf Platz 17 im Jahr 2015. Die Sprache lehnt sich in großen Teilen an die Syntax von Java an, ist gleichzeitig aber auch Vorbild für viele Java-Features. Der Einstieg fällt Java-Entwicklern dadurch besonders leicht. Vor allem mit dem erfolgreichen Webframework Grails hat sie viele Anhänger gefunden. Ihre Beliebtheit hat sie auch den vielfältigen Einsatzmöglichkeiten zu verdanken. Von einfachen Skripten, über umfangreiche Tests mit Spock, bis hin zu komplexen Applikationen mit durchgehender statischer Typisierung à la Java, deckt Groovy jedes Gebiet ab. Durch ihre Nähe interagiert sie mit Java laut der Groovy-Webseite nahtlos. Aber die dynamischen Sprachfeatures verursachen an bestimmten Stellen doch Probleme. Im Laufe des Artikels wird klar, wie gut die Integration mit Java tatsächlich funktioniert.
Primitive Datentypen als Objekte
Als erstes ist es wichtig, sich über die primitiven Datentypen einen Überblick zu verschaffen, um eine Basis für weitere Erkundungen zu schaffen. Bei primitiven Datentypen gibt es glücklicherweise keine Überraschungen, da es die gleichen sind wie in Java. Tatsächlich sind für Groovy durch seine Philosophie „Everything is an object“ auch primitive Datentypen Objekte. Ein Ausdruck wie 42.toString() würde keine Exception werfen. Dieses Verhalten wird mit Autoboxing erreicht, das jeden primitiven Datentyp mit seinem entsprechenden Wrapper-Typen umgibt. Beim Umgang mit Frameworks, die primitive Datentypen erwarten, sollen diese explizit benutzt werden.
class Person { String name Integer age Person(name = "Anonymous", age = 0) { this.name = name this.age = age } def increaseAge(Integer years) { this.age += years } }
Der Compiler erzeugt eine ganze Reihe von Konstruktoren für diese Klasse. Das liegt an den Default-Parametern. Eine Instanz lässt sich in Java wie gewohnt erzeugen:
Person nicole = new Person("Nicole", 30); Person zoe = new Person("Zoe"); Person amelie = new Person("Amelie", 1);
Man beachte den fehlenden Konstruktor für eine Person, bei der nur das Alter gesetzt wird. Dieser existiert nicht, da in Java für einen Parameter keine eindeutige Namenszuordnung gemacht werden kann. Die Zuordnung erfolgt sequenziell.
Eine wirklich angenehme Sache sind die generierten Getter und Setter für Klassenvariablen:
nicole.getName(); // Nicole amelie.setName("Amy");
Methoden in Groovy geben immer den letzten berechneten Wert zurück. Die Methode increaseAge gibt deshalb Object zurück:
nicole.increaseAge(1); // returns Object