Fluently Groovy PDF
Fluently Groovy PDF
Fluently Groovy PDF
26 Mar 2008
This tutorial is for Java™ developers unfamiliar with Groovy, who want a quick and
easy introduction to the basics. Get started with Groovy's simplified variation of the
Java syntax and learn about essential features like native collections, built-in regular
expressions, and closures. Write your first Groovy class, and then see how easily you
can use JUnit to test it. You'll walk away from this one-hour tutorial with a fully
functioning Groovy development environment and the skills to use it. Best of all, you'll
have learned first-hand how to use Groovy and Java code together in your everyday
Java application development.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 51
developerWorks® ibm.com/developerWorks
sometimes a lot faster — than you would if you were writing pure Java code.
In this tutorial, you'll get to know Groovy, a dynamic language that sits as
comfortably on the Java platform as does the Java language itself.
Objectives
This tutorial guides you step-by-step through the fundamental concepts of Groovy.
You will learn about Groovy collections, Groovy classes, and, of course, the Groovy
syntax. When you are done with this one-hour tutorial, you will understand the
benefits of using Groovy with Java (and vice versa), and you'll be set to start using
Groovy in your everyday Java development.
Prerequisites
To get the most from this tutorial, you should be familiar with Java syntax and the
basic concepts of object-oriented development on the Java platform.
System requirements
To follow along and try out the code for this tutorial, you need a working installation
of either
• A system supporting either the Sun JDK 1.5.0_09 (or later) or the IBM
JDK 1.5.0 SR3 with at least 500 MB of main memory
• At least 20 MB of disk space to install the software components and
examples covered
The instructions and examples in the tutorial are based on a Microsoft Windows
operating system. All the tools covered in the tutorial also work on Linux and Unix
systems.
Fluently Groovy
Page 2 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
What is Groovy?
Groovy is an alternate language for the JVM — alternate meaning that you can use
Groovy for Java programming on the Java platform in much the same way you
would use Java code. Groovy code combines well with Java code when writing new
applications, and can also be used to extend existing ones. Groovy currently is in
version 1.5.4 and works on the Java 1.4 and Java 5 platforms, as well as Java 6.
One nice thing about Groovy is that its syntax is very similar to the syntax in the
Java language. While Groovy's syntax was inspired by languages like Smalltalk and
Ruby, you can think of it as a simpler, more expressive variation on the Java
language. (Ruby is different from Groovy in this regard, because its syntax is quite
unlike Java syntax.)
Many Java developers take comfort in the similarity between Groovy code and Java
code. From a learning standpoint, if you know how to write Java code, you already
kind of know Groovy. The main difference between Groovy and the Java language is
that Groovy lets you write less code (sometimes far less!) to accomplish the same
tasks you might labor over in your Java code.
Groovy shortcuts
As you begin playing with Groovy, you'll find that it makes everyday programming
activities much quicker. You'll know a lot about Groovy's syntactic shortcuts by the
time you're done with this tutorial. For now, just consider these highlights:
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 51
developerWorks® ibm.com/developerWorks
Groovy extras
While Groovy permits you to drop a few elements from Java's syntax, it also adds
new features, like native collections, built-in regular expressions, and closures. In
normal Java code, if you want to create a list of items, you first import
java.util.ArrayList (for example), and then programmatically initialize an
ArrayList instance, and then add items to it. In Groovy, lists and maps are built
into the syntax — you don't need to import anything. Regular expressions also don't
require additional imports or objects; they are created via a special Groovy syntax.
About closures
Closures are an exciting addition to any Java developer's bag of tricks. While these
magical constructs are slated to become part of normal Java syntax in an upcoming
Java release (most likely Java 7), they are already available in Groovy today. You
can think of a closure as an executable code block that can be defined and then
executed at a later point. You can do many neat things with these powerful
constructs, though they're most known for making iteration easier. Start using
Groovy and it's possible you'll never need to type an instance of Iterator again.
Dynamic Groovy
Technically speaking, Groovy is one of those loosely typed, dynamic languages
you've probably been hearing so much about lately. In this regard, Groovy is quite
different from the Java language, which is a statically typed language. In Groovy,
types are optional, so you don't have to type String myStr = "Hello"; to
declare a String variable.
What's more, Groovy code can alter itself at runtime quite easily. This essentially
means that, at runtime, objects can easily be endowed with new methods and
properties. This entire realm of programming, known as metaprogramming, is well
supported in Groovy. You'll have the chance to learn more about Groovy's dynamic
nature as you progress through this tutorial. For now, suffice it to say that you'll be
surprised by how easily Groovy facilitates working with XML or normal
java.io.File instances.
Two of a kind
Anything you write in Groovy can be compiled into a normal Java class file and
re-used in Java code. Likewise, anything you write in normal Java code can be
reused in Groovy. As a result, you can easily use Groovy to write unit tests for Java
Fluently Groovy
Page 4 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
code, for instance. And if you write a handy utility in Groovy, you can also use that
utility in your Java programs.
Just to take one example, once you see how easy it is to navigate collections using
Groovy, you'll never work with them in Java again. Being able to code quickly in
Groovy also means receiving feedback sooner, not to mention the satisfaction of
crossing tasks off of your to-do list. At a high level, if you can put code in front of
stake-holders more quickly, you can give them more releases in a shorter time. In
essence, Groovy lends itself more to Agile development than Java does.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 51
developerWorks® ibm.com/developerWorks
install Groovy, I'll show you some code. First, I give you a quick reminder of what it is
like to create, compile, and run a standard Hello World example in Java; then you
see the same procedure in Groovy code. Comparing the two examples makes it
easy to appreciate the difference between the two languages.
I've omitted a package for this simple HelloWorld class and tried not to use any
superfluous coding conventions for printing to the console. The next step is to
compile this class via javac, as follows:
c:>javac HelloWorld.java
c:>java HelloWorld
So far so good — you passed Java 101 conceivably long ago, so this was just a
refresher. Next, see the same process in Groovy.
What's more, Groovy makes everyday coding activities easier; for instance, Groovy
permits you to type println instead of System.out.println. Groovy is smart
enough to know you mean System.out when you type println.
Fluently Groovy
Page 6 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Note that there is no class structure around the phrase. There isn't a method
structure either! I also used println instead of System.out.println.
Assuming I've saved my code into a file called MyFirstExample.groovy, I can run this
example by simply typing
c:>groovy MyFirstExample.groovy
That's all it takes to get the words "Hello World!" printed out on my console.
Shortcuts in action
You might notice that I didn't have to compile the .groovy file. That's because
Groovy belongs to the family of languages known as scripting languages. One of the
defining qualities of scripting languages is that they can be interpreted at runtime. (In
Java, bytecode is also interpreted and generated as a result of compiling source
code. The difference is that scripting languages interpret source code directly.)
Groovy permits you to drop the compilation step entirely, though you could do it, if
you wanted to, using the Groovy compiler, groovyc. Compiling Groovy code with
groovyc yields normal Java bytecode that I can then run via the java command.
This is a key aspect of Groovy that is often overlooked: Anything you write in Groovy
can be compiled and run via the normal Java runtime.
As for running the code, if I wanted to be even more terse I could type
That would achieve the same result without any file definition at all!
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 7 of 51
developerWorks® ibm.com/developerWorks
Figure 1 shows the dialog box you are presented with after you did the steps above:
Next, you are presented with a dialog box containing two choices. Select the radio
button that says Search for new features to install. Click the Next button and then
select New Remote Site.... You are presented with a new dialog box, which has two
fields to fill in: the name of the new location and the URL for that location, as Figure
2 shows:
Figure 2. Make sure you provide a valid URL for your new remote site
Fluently Groovy
Page 8 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 9 of 51
developerWorks® ibm.com/developerWorks
Wrap it up
After you've clicked the Finish button, you should be presented with a Search
Results dialog box. Ensure once again that you've selected the "Groovy plugin" box
and hit the Next button. Figure 4 shows this step:
Fluently Groovy
Page 10 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
After you confirm a number of things, you'll download the plugin, after which you
may have to restart Eclipse.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 11 of 51
developerWorks® ibm.com/developerWorks
Fluently Groovy
Page 12 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 13 of 51
developerWorks® ibm.com/developerWorks
From there, find the Groovy folder and select Groovy Class — you should see a
dialog box like the one in Figure 8.
Fluently Groovy
Page 14 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Click the Next button and you'll be asked to give the class a name. Type
HelloWorld.
For now, you can leave the HelloWorld Groovy class in the default package, as
Figure 9 shows.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 15 of 51
developerWorks® ibm.com/developerWorks
While this may seem like a lot of steps, it isn't all that different from creating a normal
Java class.
class HelloWorld {
static void main(args) {
}
}
Fluently Groovy
Page 16 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
That looks an awful lot like the Java HelloWorld example from earlier. Note,
though, that it contains no public modifiers. Also, if you look closely at the
argument to the main method, note that there isn't a type.
Now go ahead and put a println "Hello World" inside of the main method so
it looks like this:
class HelloWorld {
static void main(args) {
println "Hello World"
}
}
You should be able to right-click within the source code editor and select the
Compile Groovy File option, as Figure 10 shows.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 17 of 51
developerWorks® ibm.com/developerWorks
Next, right-click again, and select the Run As option, and then select the Groovy
option. You should see "Hello World" printed in your Eclipse console, as Figure 11
shows.
Fluently Groovy
Page 18 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Hello, Java!
Just to convince yourself that Groovy is Java, go ahead and put public modifiers in
front of the HelloWorld class declaration and the method declaration, like this:
There's no reason this code shouldn't run like it did before. But, if you still aren't
convinced, try putting a String[] before the args parameter:
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 19 of 51
developerWorks® ibm.com/developerWorks
You've come this far, so you might as well replace println with
System.out.println — and don't forget to add parentheses for good measure.
Now you're back to where you started with the original Hello World example written
in Java code. The question is, which example was easier to write?
Note how the original Groovy-based HelloWorld class lacked any public
modifiers, any types (no String[]), and offered the shortcut println without
parentheses to boot.
Hello, Groovy!
If you want to, you can turn this process inside out. Just go back to the Java-based
Hello World example, remove everything in the file except the System.out line and
then, while you're at it, remove the System.out and the parentheses. Here's what
you're left with:
Run it!
Groovy code is 100 percent compliant with Java bytecode, as this exercise proves.
Inside Eclipse, select the Run menu option Open Run Dialog.... Select a new Java
Application configuration. Make sure the project is your Groovy project. For the
Main class, hit the Search button and find your HelloWorld class. Note that word
class, which implies that the Eclipse Groovy plugin has compiled your .groovy file
into a .class file.
You can see this entire process in action below in Figure 12 — it should look familiar
to you if you've run Java classes before in Eclipse.
Figure 12. Groovy code is 100 percent compliant with Java bytecode
Fluently Groovy
Page 20 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Hit the Run button and what do you see? Indeed, "Hello World!" has never been so
revealing.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 21 of 51
developerWorks® ibm.com/developerWorks
If you think about it, though, the characters to the right of the equals sign already
imply that String is the type of the variable value. Accordingly, Groovy permits
you to drop the String type variable in front of value and replace it with def.
Run it!
Go ahead and edit your HelloWorld.groovy file to look like this:
Run this code and you should see the same old "Hello World" on the console. Now,
replace the String variable type with def and re-run the code. Do you notice the
same thing?
Rather than printing the value of message, you can print its type with the following
call:
def message = 12
println message.class
Fluently Groovy
Page 22 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
The numerical value for the message variable looks like Java's primitive int type.
Running this code reveals that Groovy makes it an Integer, however. That's
because "everything is an object" in Groovy, remember?
Go ahead and play around with this code. Make message whatever you'd like it to
be: Groovy will do its best to infer its type at runtime.
See, you only need to use the def keyword when declaring a freestanding variable
in a method; you don't need the def keyword for parameters in method declarations.
You also don't need them in, say, a for loop declaration, which means you don't
need to write (int x = 0; x < 5; x++). Instead, you can drop the int and
leave it blank.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 23 of 51
developerWorks® ibm.com/developerWorks
class the same way you created HelloWorld. Call this class MethodMadness and
remove the auto-generated class body: you're going to define a freestanding
repeat function instead. Now type this into your console:
def repeat(val){
for(i = 0; i < 5; i++){
println val
}
}
At first, this little function may look strange to your Java-trained eyes (in fact, it looks
a lot like JavaScript). But what you're seeing is Java code; it's just written
Groovy-style.
Inside MethodMadness
The repeat function takes one variable, val. Note how the parameter doesn't
require a def. The body of the method is, essentially, a for loop.
repeat("hello
world")
prints "hello world" five times. Note how the for loop allowed me to drop the int. A
for loop without a variable type is a bit shorter than the usual Java fare. Now see
what happens when you throw ranges into the mix.
Ranges in Groovy
A range is a sequence of values. For example, "0..4" denotes the inclusive integers
0, 1, 2, 3, 4. Groovy also supports exclusive ranges, where "0..<4" means 0, 1, 2,
3. You can also create a range of characters: "a..e" is equal to a, b, c, d, e.
"a..<e" would be all those values less e.
Ranges facilitate looping quite nicely. For instance, your previous for loop
incremented an integer from 0 to 4 like so:
A range would make that for loop cleaner and nicer to read:
Fluently Groovy
Page 24 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
def repeat(val){
for(i in 0..5){
println val
}
}
Setting up a range
If you try running this example you may notice a small problem: "Hello World" prints
six times instead of five. There are three ways to fix this:
for(i in 0..4)
def repeat(val){
for(i in 1..5){
println val
}
}
def repeat(val){
for(i in 0..<5){
println val
}
}
Any way you cut it, you're back to where you started — printing "Hello World" five
times.
Having to specify the number of desired repetitions every time you make a call to
repeat can get old, especially if you are already comfortable with the default
behavior (that is, repeating five times).
Groovy supports default parameter values which allow you to specify a parameter's
default value in the formal definition of a function or method. Callers to the function
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 25 of 51
developerWorks® ibm.com/developerWorks
can opt to omit the parameter and accept the default value.
Using the repeat function from earlier, if you want to provide the option to allow
callers to specify a repeat value, you can code it as follows:
repeat("Hello World", 2)
repeat("Goodbye sunshine", 4)
repeat("foo")
results in "Hello World" being printed two times, "Goodbye sunshine" four times, and
"foo" the default amount of five times.
Groovy, on the other hand, facilitates using collections directly within the language.
In Groovy you do not need to import a specialized class, nor do you need to initialize
an object. A collection is a native member of the language itself. Groovy also makes
working with collections (or lists, if you like) quite easy by intuitively aiding in adding
and removing items.
Fluently Groovy
Page 26 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Note how the assert phrase proves that ranges are instances of
java.util.List. Go ahead and run this code to verify the range is now a
collection of type List.
Extensive support
Groovy's collections support is extensive, and the beauty of it is that underneath the
magic, everything is a normal Java object. Every Groovy collection is an instance of
java.util.Collection or java.util.Map.
As mentioned earlier, Groovy's syntax offers native lists and maps. For example, try
adding the following two lines of code to the Ranger class:
You'll note that the coll object looks like an array in the Java language. Actually,
it's a Collection. To achieve the same instance of a collection in normal Java
code, you'd have to do something like this:
In Java code, you have to use the add() method to add items to the instance of the
ArrayList.
Add it up
Groovy gives you a number of ways to add something to a list of items — you can
use the add() method (because the underlying collection is a normal ArrayList
type), but there are a number of shortcuts you could also try.
For example, each line in the following code adds something to the underlying
collection:
coll.add("Python")
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 27 of 51
developerWorks® ibm.com/developerWorks
Note how Groovy enables operator overloading — the << operator is overloaded to
permit adding items into a collection. Also, you can directly add items via a positional
argument. In this case, as the collection only had four items in it, the [5] operator
places "Perl" in the last spot. Go ahead and print out the collection and see it for
yourself.
Retrieving is easy
If you need to obtain a particular item from a collection, you can grab it via a
positional argument like the one above. For example, if you wanted to obtain the
second item, "Java," you could write something like this (remember that collections
and arrays are zero-based):
Groovy also permits you to add and subtract collections from each other, like so:
Note that in the above snip you've created a new collection instance, as the last line
in the code implies.
join() and count() are just two of the many different convenience methods
available to call on any list of items. The spread operator is a particularly handy
utility which facilitates calling a method on each item in a collection without having to
iterate over the collection.
Given a list of Strings, if you'd like to capitalize all of them, you can write
Fluently Groovy
Page 28 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Note the *. notation. For each value in the above list, toUpperCase() is invoked,
producing a collection with each String instance capitalized.
Note that the keys in a Groovy map don't have to be Strings. In this case, name
looks like a variable, but behind the scenes Groovy will make it a String.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 29 of 51
developerWorks® ibm.com/developerWorks
Now go ahead and create a new class called Mapper and add that code. Then add
the following line just to verify you're working with real Java code underneath:
You can see that Groovy makes use of Java's LinkedHashMap type, which means
you can put and get items from this hash using normal Java idioms.
hash.put("id", 23)
assert hash.get("name") == "Andy"
hash.dob = "01/29/76"
The . notation also works for obtaining items. For instance, here's how to grab the
value of dob:
Certainly the . is more groovy than calling get(), don't you think?
Positional maps
You can also use pseudo-positional syntax to put items into a map and obtain items
from one, as follows:
Note, though, that when obtaining items from a map via the [] syntax, you must
reference items as Strings.
Fluently Groovy
Page 30 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
No more Iterator
While you did quite a bit of coding with collections in the previous sections, you've
yet to actually iterate over one. Of course, you know that Groovy is Java, so you can
always grab an instance of the old Java Iterator, if you want, and loop over a
collection like so:
You don't actually need the type declaration inside the for loop, though, because
Groovy has made iteration a direct member of any collection. In this case, rather
than having to obtain an Iterator and directly manipulate it, you can just iterate
over a collection directly. What's more, the behavior that is normally intended to
reside inside a loop construct (such as the println in the body of for loop) is then
put inside a closure. Before we get too far, let's see this in action.
Note how each is called directly on the acoll instance, which you already know is
of type ArrayList. After the each call, a new syntax is introduced — {, and then
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 31 of 51
developerWorks® ibm.com/developerWorks
some code, followed by }. The block of code signified by the {} is what's known as
a closure.
Execute it
Closures are blocks of executable code. They don't require names, and they can be
executed after they've been defined. So, in the case above, the nameless closure
whose body has the behavior of printing it (I'll explain what it is shortly) is called
for every value in the acoll collection type.
At a high level, the code between the {} is executed three times, thus printing what
you see in Figure 13.
The it variable inside the closure is a keyword that points to the individual value of
the outside collection being invoked — it is a default value that can easily be
overridden by passing a parameter into the closure. So for instance, the following
code does the same exact thing, but uses its own item variable:
Ubiquitously iterating
Closures appear frequently in Groovy; however, you'll use them most often when
iterating over a series of values. Keep in mind, a series of values can be represented
in more ways than just as a list — for example you can iterate over a map, a
String, a JDBC Rowset, a line in a File, and more.
Fluently Groovy
Page 32 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
If you wanted to iterate over the hash object from the previous section of mapping in
Groovy, you could write the following:
Note how closures also permit multiple parameters — in this case, the code above
contains two parameters (key and value).
The above code is verbose compared to Groovy's, isn't it? If you find yourself
working a lot with collections, it just makes sense to do it in Groovy.
Total iteration
Remember, anything that is a collection or series of some sort can be iterated as
shown in the code below.
"ITERATION".each{
println it.toLowerCase()
}
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 33 of 51
developerWorks® ibm.com/developerWorks
For instance, create a ClosureExample object via Eclipse and leave in the default
class syntax it gives you. In the resulting main() method, add this bit of code:
This code is a closure named excite. This closure takes one parameter (named
word) and returns a String with the word variable along with two exclamation
points. Note the use of substitution within the String instance. Using the
${value}syntax within a String tells Groovy to replace the value of a particular
variable within the String itself. Think of this syntax as a handy way to do the
equivalent of return word + "!!".
Delayed execution
Now that you have a closure, it's time to actually use it. You can call closures one of
two ways: either directly or via the call() method.
Using your ClosureExample class, go ahead and add the following two lines of
code below the closure's definition:
As you can see, either style of invocation works, though calling it directly is more
concise. Don't forget that closures are first-class objects in Groovy too — they can
be passed around as parameters and of course, executed at some later point.
Replicating the same behavior in normal Java is possible, but not exactly easy. But
that's no surprise to you by now, right?
Fluently Groovy
Page 34 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Of course, you've been working with classes for a while in this tutorial already: the
last few examples you coded were in the main() method of various classes. And,
as you already know, you can define classes in Groovy just like you do in your Java
code. The only difference is, you don't need to put in public modifiers and you can
drop types for method parameters. This section introduces you to all the other things
you can do with Groovy classes.
The first step, naturally, is to create a class in Groovy called Song. This time, create
a package structure for it too — go ahead and create a package name like
org.acme.groovy.
Once you've created this class, remove main() that was automatically generated
for you by the Groovy plugin.
A song has a few properties — the artist who created it, the name of the song, and a
genre, to name a few. Add those properties to your newly created Song class, like
so:
package org.acme.groovy
class Song {
def name
def artist
def genre
}
So far so good, right? It's nothing too complex for the new Groovy developer!
All this means that if you want to use your new Song class in another Groovy class
or Java class, you'll have to import it (unless, of course, the code that will use Song
resides in the same package as Song).
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 35 of 51
developerWorks® ibm.com/developerWorks
Accordingly, go ahead and create a new class, called SongExample and put it into
another package structure, say org.thirdparty.lib.
You should now be looking at some code that looks like this:
package org.thirdparty.lib
class SongExample {
static void main(args) {}
}
Class relationships
Now it's time to use that Song class. First import the instance and add this code into
SongExample's main() method.
package org.thirdparty.lib
import org.acme.groovy.Song
class SongExample {
static void main(args) {
def sng = new Song(name:"Le Freak",
artist:"Chic", genre:"Disco")
}
}
Now that's a Song instance you can dance to! Look closely, though, at the
initialization of the Song class you defined earlier. Do you notice anything special?
You should notice the auto-generated constructor.
Class initialization
Groovy automatically gives you a constructor that takes a map of name-value pairs,
which correspond to class properties. This, by the way, is an out-of-the-box feature
of Groovy — for any properties you define in a class, Groovy permits you to pass a
map full of values into a constructor. The use of a map does have implications; for
instance, you don't actually have to initialize every property of an object.
You are also free to directly manipulate properties of a class, like so:
Fluently Groovy
Page 36 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Looking at this code, it is evident that not only did Groovy create a constructor that
permits passing in a map of properties and their values, but you can semi-directly
access properties via the . syntax. Moreover, Groovy also generated normal setter
and getter methods.
sng3.setGenre "Disco"
assert sng3.genre == "Disco"
In Groovy, for methods that take parameters, you can optionally drop the
parentheses — in some ways, doing so makes the code a bit easier to read.
Method overriding
So far you've managed to create a few instances of the Song class. Although, right
now they don't do anything particularly interesting. You can print one using the
following command:
println sng3
All that does is print the default toString() implementation of all objects in Java,
namely the class and it's hashcode (that is, org.acme.groovy.Song@44f787).
Let's see what happens when you override the default toString() implementation
to print something a bit nicer.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 37 of 51
developerWorks® ibm.com/developerWorks
String toString(){
"${name}, ${artist}, ${genre}"
}
Based on what you've learned in this tutorial, you were able to drop the public
modifier on the toString() method. You still needed to specify a return type
(String) in order to actually override the proper method. The body of the method is
tersely defined — but where is the return statement?
No return needed
You've probably already figured out that in Groovy you can omit the return
statement. Groovy assumes the last line in a method should be returned. So in this
case, a String is returned containing the values of the class's properties.
Go ahead and re-run the SongExample class. You should see something a bit more
interesting when you do. The toString() method returns a description instead of a
hashcode.
Specialized access
Groovy's auto-generation is handy for a few features, but sometimes you need to
override default behavior. For instance, let's say you need to override the
getGenre() method in the Song class, so that the returned String is all
capitalized.
Providing this new behavior is quite easy, just define a getGenre() method. You
can have either have the method's declaration return a String or you can omit it
entirely if you wish. Go ahead and do the simplest possible thing:
def getGenre(){
genre.toUpperCase()
}
Like before, your simple method omits a return type and a return phrase. Now run
your SongExample class again. You should see something unexpected ---there is
now a nullpointer exception.
Nullpointer safety
If you've followed along so far, you should at some point have added this line to your
SongExample class:
Fluently Groovy
Page 38 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
The result was an assertion failure when you re-ran SongExample — which is why
all that ugly red text printed out in your Eclipse console. (Sorry about pulling such a
dirty trick, by the way.)
Fortunately, you can easily fix the error: just add the following line of code to the
SongExample class:
println sng2.artist.toUpperCase()
But wait, now more red text is streaming down your console — what happened?!
Nasty nulls
If you remember, the sng2 instance didn't define an artist value. As a result, a
Nullpointer exception was generated when you invoked the toUpperCase()
method.
Luckily, Groovy provides a safety net, via the ? operator — preceding a method call
with ? is like putting a conditional in front of the call which guards calling a method
on a null object.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 39 of 51
developerWorks® ibm.com/developerWorks
String toString(){
"${name}, ${artist}, ${getGenre()}"
}
def getGenre(){
genre?.toUpperCase()
}
The ? operator is quite useful from time to time and most certainly cuts down on
conditional phrases.
Fluently Groovy
Page 40 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
You are presented with the Add Library dialog box like the one in Figure 15.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 41 of 51
developerWorks® ibm.com/developerWorks
Select JUnit and hit the Next button. You should see a dialog box like the one in
Figure 16. Select JUnit3 or 4 — the choice is entirely up to you — and hit the Finish
button.
Fluently Groovy
Page 42 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Note that you can select the Song class that you defined in Groovy. Figure 17
demonstrates this step:
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 43 of 51
developerWorks® ibm.com/developerWorks
Select that class and hit OK (you should see a dialog box similar to the one in Figure
18) and then hit the Finish button in the New JUnit Test Case dialog.
Fluently Groovy
Page 44 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
package org.acme.groovy;
import org.junit.Test;
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 45 of 51
developerWorks® ibm.com/developerWorks
Test toString
Obviously, you want to verify that the toString() method is clean, so what's your
first step? If you thought to yourself "import the Song class" you are thinking too
hard — the Song class is in the same package. Consequently, the first step is to
create an instance of it.
In creating an instance of Song to test, note that you don't have the ability to fully
initialize an instance via a map passed into a constructor — what's more, if you
attempt auto-completion of the instance's setter methods, see that each setter takes
an Object rather than a String (look closely at Figure 19, just in case). Why is
that?
Fluently Groovy
Page 46 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Now recall that when you defined the Song class, you omitted each property's type.
Groovy, being pretty groovy, naturally made each property an Object. So, when
you attempt to use the Song class in normal Java, you are presented with a lot of
getters and setters that all have Object as both a return type and parameter type.
package org.acme.groovy
class Song {
def name
String artist
def genre
String toString(){
"${name}, ${artist}, ${getGenre()}"
}
def getGenre(){
genre?.toUpperCase()
}
}
Now, go back to your JUnit test, and tap the auto-completion shortcut on your Song
instance — do you see what I see?
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 47 of 51
developerWorks® ibm.com/developerWorks
@Test
public void testToString(){
Song sng = new Song();
sng.setArtist("Village People");
sng.setName("Y.M.C.A");
sng.setGenre("Disco");
Assert.assertEquals("Y.M.C.A, Village People, DISCO",
sng.toString());
}
Coding the remainder of this test case is trivial. What it nicely demonstrates is that
anything you do in Groovy can be easily re-used in your Java programs. Don't forget
that the opposite is also true. Everything you do and have written in the Java
language is also available to you in Groovy.
Fluently Groovy
Page 48 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
I hope you've had fun on this first journey toward Groovy fluency. You've played
around with Groovy's syntax, created a few classes that exercised its
productivity-enhancing features, and seen how easy it is to test a Groovy class using
Java. You've also encountered some of the pitfalls common to first-time Groovy
developers, and seen how to work around them without creating too much of a
mess.
While you probably don't consider yourself quite fluent in Groovy at this point, you've
taken the first steps. You can use what you've learned so far as a basis for writing
your own first Groovy programs — after all, you've got your dual Groovy-and-Java
programming environment all set up! For an interesting exercise, try setting up your
next round of automated builds with Gant, an Ant-based build tool that uses Groovy
rather than XML to define the build. Once you're more comfortable with the language
you can try building a Web application module using Groovy on Grails — which,
incidentally, is the subject of my next tutorial.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 49 of 51
developerWorks® ibm.com/developerWorks
Resources
Learn
• Practically Groovy (Andrew Glover, developerWorks, August 2004 through
September 2006): Go beyond basics with Andrew's introductions to Groovy
builders and templates, Ant scripting with Groovy, Groovy on the server side,
smooth operators, Groovy's Meta Object Protocol, and more.
• "Mastering Grails: Build your first Grails application" (Scott Davis,
developerWorks, January 2008): Get started with Grails, a modern Web
development framework that seamlessly integrates legacy Java code with the
flexibility and dynamism of Groovy.
• "Secrets of lightweight development success, Part 7: Java alternatives" (Bruce
Tate, developerWorks, September 2005): Find out what makes a language
productive, or not, in this high-level discussion of closures, continuations,
reflection, and metaprogramming.
• "What's New in Groovy 1.5" (InfoQ, Guillaume Laforge, December 2007):
Groovy's project manager highlights Groovy's new support for Java 5
annotations, generics and enums.
• "Groovy-power automated builds with Gant" (Klaus Berg, JavaWorld, February
2008): Find out why some Java developers are choosing Gant as a more
expressive alternative for complex builds.
• The Disco Blog's Groovy articles (Andrew Glover, thediscoblog.com): Where
Andrew writes about various topics related to Groovy, such as unit testing,
metaprogramming, and advanced Groovy development techniques.
Get products and technologies
• IBM developer kit for Java technology 1.5.0 SR3: Powerful support for Groovy
development on the Java platform.
• Sun JDK 1.5 or later: You'll need at least version 1.5.0_09 to follow the
examples in this tutorial.
• Eclipse IDE: Set up your Groovy development environment easily with the
Eclipse Groovy Plugin.
• Groovy: Hosted by Codehaus.
• JUnit: Examples are compatible with JUnit 3 or JUnit 4.
Discuss
• The Groovy Zone: The DZone community for Groovy and Grails developers.
• Improve your code quality: Andrew Glover's developerWorks discussion for
Fluently Groovy
Page 50 of 51 © Copyright IBM Corporation 1994, 2008. All rights reserved.
ibm.com/developerWorks developerWorks®
Trademarks
Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the
United States, other countries, or both.
Fluently Groovy
© Copyright IBM Corporation 1994, 2008. All rights reserved. Page 51 of 51