{"id":2820,"date":"2014-05-16T14:39:52","date_gmt":"2014-05-16T12:39:52","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2820"},"modified":"2014-05-16T14:39:52","modified_gmt":"2014-05-16T12:39:52","slug":"inselraus-groovy","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2014\/05\/inselraus-groovy\/","title":{"rendered":"Inselraus: Groovy"},"content":{"rendered":"<p>Groovy (http:\/\/groovy.codehaus.org\/) ist eine objektorientierte Skriptsprache, die auf einer JVM l\u00e4uft und vollen Zugriff auf alle Java-Bibliotheken bietet. Die Sprache hat viele interessante Eigenschaften, die sie zu Java X machen. Groovy setzt auf der Standard-Java-Syntax auf und erweitert diese.[1] Einige H\u00f6hepunkte:<\/p>\n<table>\n<thead>\n<tr>\n<td width=\"250\"><strong>Groovy-Feature<\/strong><\/td>\n<td width=\"411\"><strong>Beispiel<\/strong><\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td width=\"250\">Statt System.out.print(\u2026)\/println(\u2026) reicht ein print bzw. println, und dann muss das Argument auch nicht in runden Klammern stehen.<\/td>\n<td width=\"411\">println 1 + 2<br \/>\nprint &#8222;Wow&#8220;<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Anweisungen m\u00fcssen nicht immer mit einem Semikolon abgeschlossen werden, sondern nur dann, wenn mehrere Anweisungen in einer Zeile stehen.<\/td>\n<td width=\"411\">print &#8222;Wow&#8220;<br \/>\nprint &#8222;Wow&#8220;; print &#8222;Wow&#8220;<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Variablen m\u00fcssen nicht mit einem Typ deklariert werden, das gilt auch bei catch oder Methoden\/Konstruktoren.<\/td>\n<td width=\"411\">def age = 40<br \/>\ndef greet( name ) { print &#8222;Hallo &#8220; + name }<br \/>\ntry { } catch ( e ) { }<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Zeichenketten lassen sich mit einfachen oder doppelten Anf\u00fchrungszeichen angeben. Einzelne Zeichen (char\/Character) m\u00fcssen besonders aufgebaut werden.<\/td>\n<td width=\"411\">print &#8222;Ja&#8220; == &#8218;Ja&#8216;\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ true<br \/>\ndef sign = &#8222;-&#8220; as char<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Strings in doppelten Anf\u00fchrungszeichen sind besondere GStrings: Enthalten sie $variable bzw. ${ausdruck}, so wird der Inhalt der Variablen bzw. der ausgewertete Ausdruck eingesetzt.<\/td>\n<td width=\"411\">def one = 1<br \/>\nprint &#8222;$one plus $one macht ${1+1}&#8220;<br \/>\n\/\/ 1 plus 1 macht 2<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Strings k\u00f6nnen \u00fcber mehrere Zeilen laufen, wenn sie in &#8222;&#8220;&#8220; oder &#8220;&#8216; eingeschlossen sind \u2013 folgt ein Backslash am Ende der Zeile, wird kein Zeilenumbruchzeichen eingef\u00fcgt.<\/td>\n<td width=\"411\">print &#8222;&#8220;&#8220;<br \/>\nZeile 1<br \/>\nZeile 2\\<br \/>\nWeiter mit Zeile 2<br \/>\n&#8222;&#8220;&#8220;<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Alles ungleich 0 und null ist true.<\/td>\n<td width=\"411\">if ( 1 ) print &#8218;Zweig wird genommen&#8216;<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Groovy definiert einen neuen Datentyp f\u00fcr Bereiche (engl. ranges).<\/td>\n<td width=\"411\">def numbers1 = 0..9<br \/>\ndef numbers2 = 0..&lt;10<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Erweiterte Z\u00e4hlschleife unter Ber\u00fccksichtigung von Bereichen, bzw. rechts von in steht ein Iterable wie beim erweiterten for.<\/td>\n<td width=\"411\">for ( i in 0..&lt;10 )<br \/>\nprint i\u00a0 \/\/ 0123456789<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">== bei Referenzen bedeutet equals(\u2026)-gleich; ein Identit\u00e4tsvergleich realisiert is(\u2026).<\/td>\n<td width=\"411\">def heinz = &#8218;Heinz&#8216;<br \/>\nprint heinz == &#8218;Heinz&#8216;\u00a0 \/\/ true<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Operatoren k\u00f6nnen \u00fcberladen werden, und die Anwendung von Operatoren entspricht Methodenaufrufen, etwa + von plus(\u2026), ++ von next(\u2026) oder [] von getAt(\u2026).<\/td>\n<td width=\"411\">println 1 + 2 * 3 \/\/ 7<br \/>\nprintln 1.plus(2).multiply(3) \/\/ 9<br \/>\nprintln 1.plus(2.multiply(3)) \/\/ 7<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Alle Comparable-Objekte (und damit etwa String, BigInteger, BigDecimal) k\u00f6nnen mit ==, !=, &lt;, &gt;, &lt;= und &gt;= verglichen werden. Die Ordnung liefert compareTo(\u2026).<\/td>\n<td width=\"411\">def heinz = &#8218;Heinz&#8216;<br \/>\nprint heinz &lt; &#8218;Werner&#8216;\u00a0 \/\/ true<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Ist in Java nur java.lang standardm\u00e4\u00dfig importiert, ist es bei Groovy viel mehr, etwa noch java.io, java.util, java.net und noch einige.<\/td>\n<td width=\"411\">print new File(&#8218;file.txt&#8216;).exists()<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Statt explizit auf Datenstrukturklassen f\u00fcr Listen und Mengen zur\u00fcckzugreifen, bietet Groovy eine spezielle Syntax.<\/td>\n<td width=\"411\">def primes = [ 2, 3, 5, 7]<br \/>\nprint primes[ 0 ]<br \/>\ndef dic = [ &#8218;rot&#8216; : &#8218;red&#8216;, &#8218;blau&#8216; : &#8218;blue&#8216; ]<br \/>\nprint dic[&#8218;rot&#8216;]\u00a0 \/\/ red<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Die Operatoren ?. und ?: (Elvis-Operator) verhindern null-Zugriffe.<\/td>\n<td width=\"411\">def name = &#8218;Chris&#8216;<br \/>\nprintln name ?: &#8218;Kein Name&#8216;\u00a0 \/\/ Chris<br \/>\nname = null<br \/>\nprintln name ?: &#8218;Kein Name&#8216;\u00a0 \/\/ Kein Name<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Der Zugriff auf Zeichen \u00fcber [] ist bei den Zeichenkettenklassen String, StringBuffer, StringBuilder m\u00f6glich.<\/td>\n<td width=\"411\">def s = &#8218;Ooog&#8216;<br \/>\nprint s[0]\u00a0\u00a0 \/\/ O<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Der Zugriff \u00fcber [] l\u00e4sst auch Bereiche zu.<\/td>\n<td width=\"411\">def s = &#8222;tutego&#8220;<br \/>\nprint s[ 0, 1, 3..5 ] \/\/ tugeo<br \/>\ndef t = new StringBuilder( &#8222;tutego&#8220; )<br \/>\nt[ 1..4 ] = &#8222;X&#8220;<br \/>\nprint t\u00a0 \/\/ tXo<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Der Operator &lt;&lt; h\u00e4ngt Dinge an Strings (R\u00fcckgabe ist dann StringBuffer), Listen oder Dateien an.<\/td>\n<td width=\"411\">def s = &#8218;oger&#8216;<br \/>\ndef sb = &#8218;Das ist &#8218; &lt;&lt; s &lt;&lt; &#8218; oder?&#8216;<br \/>\nprint sb\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Das ist oger oder?<br \/>\ndef file = new File(&#8222;out.txt&#8220;)<br \/>\nfile &lt;&lt; &#8222;Zeile 1&#8220;<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Regul\u00e4re Ausdr\u00fccke werden mit einer eigenen Syntax direkt von der Sprache unterst\u00fctzt; =~ ist ein find, ==~ ein match.<\/td>\n<td width=\"411\">print &#8218;2010&#8216; ==~ \/\\d+\/<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">erweitertes switch-case etwa mit regul\u00e4ren Ausdr\u00fccken und Bereichen<\/td>\n<td width=\"411\">switch ( 42 ) {<br \/>\ncase 0..100\u00a0 : println &#8218;ist zwischen 0..100&#8216;; break<br \/>\ncase Integer : println &#8218;ist Integer&#8216;; break<br \/>\ncase { it % 2 == 0 }: println &#8218;ist gerade&#8216;; break<br \/>\ncase ~\/\\d\\d\/: println &#8217;42 passt auf das Pattern&#8216;; break<br \/>\n}<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Datentyp f\u00fcr Dauer und spezielle Eigenschaften f\u00fcr Datumswerte und \u00fcberladene Operatoren zum leichten Rechnen mit dem Paket groovy.time<\/td>\n<td width=\"411\">use ( groovy.time.TimeCategory ) {<br \/>\ndef today = new Date()<br \/>\ndef tomorrow = today + 1.day<br \/>\nprint &#8222;Morgen: $tomorrow, n\u00e4chstes Jahr ${today + 1.year}&#8220;<br \/>\n}<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Closures als Codebl\u00f6cke werden unterst\u00fctzt und finden \u00fcberall in der Groovy-API Anwendung.<\/td>\n<td width=\"411\">new File( &#8222;file.txt&#8220; ).eachLine {<br \/>\nprintln it<br \/>\n}<br \/>\ndef names = [ &#8222;Charisma&#8220;, &#8220;\u00a0 &#8222;, &#8222;Tina&#8220;, &#8222;&#8220; ]<br \/>\nprint names.findAll { ! it.trim().isEmpty() }<br \/>\n\/\/ [Charisma, Tina]<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Setter\/Getter m\u00fcssen nicht aufgerufen werden; beim Zugriff ref.property wird automatisch der Setter\/Getter aufgerufen.<\/td>\n<td width=\"411\">def p = new Point( 10, 20 )<br \/>\nprint p.location.x\u00a0 \/\/ 10.0<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">In Methoden mit R\u00fcckgabe kann das Schl\u00fcsselwort return entfallen.<\/td>\n<td width=\"411\">def add( a, b ) { a + b }<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Default-Parameter bei Methodendeklarationen<\/td>\n<td width=\"411\">static tax( cost, taxRate = 19 ) {<br \/>\ncost * taxRate \/ 100<br \/>\n}<br \/>\nprintln tax( 100 )\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 19<br \/>\nprintln tax( 100, 7 )\u00a0\u00a0\u00a0 \/\/ 7<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Methoden und Klassen sind standardm\u00e4\u00dfig public, nicht paketsichtbar wie bei Java. Groovy erstellt automatisch Setter\/Getter.<\/td>\n<td width=\"411\">class Person { def\u00a0 name }<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Mit der Klassenannotation @Immutable wird ein Typ unver\u00e4nderbar, mit @Singleton ein Singleton mit einem privaten Konstruktor und \u00f6ffentlichem Attribut instance f\u00fcr die eine Instanz.<\/td>\n<td width=\"411\">@Immutable class Pair { String val1, val2 }<br \/>\n@Singleton class AppWindow { }<\/td>\n<\/tr>\n<tr>\n<td width=\"250\">Diverse Builder-Klassen erleichtern den Aufbau von hierarchischen XML- oder Swing-B\u00e4umen ebenso wie Ant-Build-Skripten.<\/td>\n<td width=\"411\">import groovy.xml.MarkupBuilder<br \/>\ndef writer = new StringWriter()<br \/>\nnew MarkupBuilder( writer ).html {<br \/>\nhead { title &#8218;Z\u00e4hlen mit Graf Zahl&#8216; }<br \/>\nbody {<br \/>\nh1 ( &#8218;Willkommen&#8216; )<br \/>\np {<br \/>\nul { (1..10).each { li it } }<br \/>\na(\u00a0href:&#8220;&#8217;http:\/\/stupidedia.org\/stupi\/Graf_Zahl&#8220;&#8216;,<br \/>\n&#8218;Graf Zahl&#8216; )<br \/>\n}<br \/>\n}<br \/>\n}<br \/>\nprintln writer<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><em>Eigenschaften von Groovy mit Beispiel<\/em><\/p>\n<h4>Groovy-Skripte in Eclipse ausf\u00fchren<\/h4>\n<p>Um Groovy-Skripte und Programme auszuf\u00fchren, bieten sich drei Wege an:<\/p>\n<ul>\n<li>\u00fcber eine spezielle Kommandozeile, die Groovy-Shell<\/li>\n<li>\u00fcber das Eclipse-Plugin<\/li>\n<li>\u00fcber die javax.script-API<\/li>\n<\/ul>\n<p>Das Eclipse-Plugin unter http:\/\/groovy.codehaus.org\/Eclipse+Plugin leistet gute Arbeit und wird st\u00e4ndig weiterentwickelt. Auf der Webseite ist der Update-Link genannt, sodass Groovy-Eclipse \u00fcber den Update-Manager installiert werden kann.<\/p>\n<ol>\n<li>W\u00e4hle dazu Eclipse Help \u2022 Install New Software\u2026<\/li>\n<li>In der Dialogbox f\u00fclle das Textfeld bei Work with mit dem Link http:\/\/dist.springsource.org\/release\/GRECLIPSE\/e4.3\/ (bzw. anderen Versionen je nach Eclipse-Version), und aktiviere Add\u2026<\/li>\n<li>Aktiviere anschlie\u00dfend Groovy-Eclipse, und f\u00fchre die Installation mit Next usw. zu Ende.<\/li>\n<\/ol>\n<p>Ist Eclipse neu gestartet und das Plugin installiert, kann jedes Java-Projekt um Groovy-Unterst\u00fctzung erweitert werden. Bei einem Java-Projekt aktiviert die Aktion Configure \u2022 Convert to Groovy Project im Kontextmen\u00fc genau diese Groovy-Unterst\u00fctzung, sodass im Projektbaum die Groovy-Bibliotheken auftauchen.<\/p>\n<p>File \u2022 New \u2022 Other\u2026 erm\u00f6glicht zum einen im Zweig Groovy das Erstellen eines neuen Groovy-Projekts (durch die Konvertierung eines existierenden Java-Projekts ist das nicht mehr n\u00f6tig) und zum anderen mit Groovy Class das Erstellen einer Groovy-Klasse. Bei dieser Option l\u00e4sst sich ein Paket- und Klassenname eingeben (etwa com.tutego.insel.script und GroovyBabe), und dann \u00f6ffnet Eclipse den Groovy-Editor.<\/p>\n<p>L\u00f6schen wir die Klassendeklaration und setzen nur die zwei Zeilen in die Datei:<\/p>\n<pre>package\u00a0com.tutego.insel.script<\/pre>\n<p>print\u00a0&#8222;Hallo\u00a0Groovy&#8220;<\/p>\n<p>Ausgef\u00fchrt wird das Groovy-Skript im Kontextmen\u00fc (oder Run-Men\u00fc) mit Run As \u2022 Groovy Skript.<\/p>\n<h4>Groovy\u00a0\u00fcber die Skript-API ausf\u00fchren<\/h4>\n<p>Um Groovy\u00a0als Skriptsprache aus einem Java-Programm heraus zu nutzen, k\u00f6nnen wir wieder auf die Skript-API zur\u00fcckgreifen. Wenn es sich bei Eclipse schon um ein Groovy-Projekt handelt, ist ein JAR schon im Klassenpfad eingebunden, und es ist nichts zu tun. Andernfalls bekommen wir von der Webseite http:\/\/groovy.codehaus.org\/Download unter Download zip: Binary Release ein fast 30 MiB gro\u00dfes ZIP-Archiv wie groovy-binary-2.2.2.zip, wo groovy-all-2.2.2.jar im Ordner embeddable liegt und das wir in den Klassenpfad mit aufnehmen.<\/p>\n<p>Ein kleines Beispiel:<\/p>\n<pre>ScriptEngine\u00a0engine\u00a0=\u00a0new\u00a0ScriptEngineManager().getEngineByName(\u00a0\"groovy\"\u00a0);<\/pre>\n<pre> System.out.println(\u00a0engine.eval(\u00a0\"(1g..42g.gcd(56g)).sum()\"\u00a0)\u00a0);\u00a0\/\/\u00a0105<\/pre>\n<pre>[1]\u00a0\u00a0\u00a0 Bis auf sehr kleine Ausnahmen ist jedes Java-Programm ein Groovy-Programm.<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Groovy (http:\/\/groovy.codehaus.org\/) ist eine objektorientierte Skriptsprache, die auf einer JVM l\u00e4uft und vollen Zugriff auf alle Java-Bibliotheken bietet. Die Sprache hat viele interessante Eigenschaften, die sie zu Java X machen. Groovy setzt auf der Standard-Java-Syntax auf und erweitert diese.[1] Einige H\u00f6hepunkte: Groovy-Feature Beispiel Statt System.out.print(\u2026)\/println(\u2026) reicht ein print bzw. println, und dann muss das Argument [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11],"tags":[],"class_list":["post-2820","post","type-post","status-publish","format-standard","hentry","category-insel"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2820","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2820"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2820\/revisions"}],"predecessor-version":[{"id":2821,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2820\/revisions\/2821"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2820"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2820"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2820"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}