Welcome to the Groovy cheat sheet! This is a condensed reference for Groovy syntax and other information that you might regularly want to look up.
1. Core types and operators
Groovy comes with a selection of the basic types you’d expect, such as strings and numbers. Most of them are part of the standard Java class library, although Groovy introduces some new literals.
1.1. Type list
Type | Literals | Notes |
---|---|---|
java.lang.String |
|
Double quotes allow embedded expressions. Slashes mean you don’t need to escape |
java.lang.Character |
|
Represents a single Unicode character. Primitive type: |
java.lang.Boolean |
|
Primitive type: |
java.lang.Byte |
|
8-bit integer. Primitive type: |
java.lang.Integer |
|
32-bit integer. Primitive type: |
java.lang.Long |
|
64-bit integer. Primitive type: |
java.math.BigInteger |
|
No upper limit on values. No primitive equivalent |
java.lang.Float |
|
32-bit, single-precision floating-point number. Primitive type: |
java.lang.Double |
|
64-bit, double-precision floating-point number. Primitive type: |
java.math.BigDecimal |
|
Exact, uncapped floating-point number. No, primitive equivalent. |
java.util.List |
|
Can contain values of any type. |
java.util.Set |
|
Can contain values of any type. |
java.util.Map |
|
String keys don’t need quotes when using the map literal. |
groovy.lang.IntRange |
|
The first literal excludes the upper bound, whereas the second includes it. The lower bound is always included. |
In addition to all the string literal variants shown in the table above, you can create multi-line strings by using three quotes in a rows. For example:
def text = """Dear sir,
Welcome to Top Bank!
"""
You can use single or double quotes, with the latter allowing you to embed Groovy expressions (the behavior matches that of the equivalent normal strings).
Line continuations allow you to split long lines of text across multiple lines of your source code:
def text = """\
one \
two \
three \
"""
assert text == "one two three"
For this to work, you can’t have any characters, even whitespace, after the backslash ('\').
1.2. Coercions
Groovy allow you to easily convert values from one type to another if the conversion is known, for example String
→ Character
, or List
→ Set
. Either declare a variable of the target type:
Set s = [1, 2, 3, 3]
char ch = 'H'
int[] a = [1, 2, 3, 4]
or use the as
operator:
def s = [1, 2, 3, 3] as Set
def ch = 'H' as char
def a = [1, 2, 3, 4] as int[]
The as
operator is more flexible as it can be used for method arguments too:
assert Character.getNumericValue('H' as char) == 17
Without the coercion, the above code would throw a MissingMethodException
.
1.3. Overloadable operators
Groovy allows you to implement operators in your own classes by implementing methods with specific signatures. You can also use the method names to look up what operators are supported by types in the Java class library and Groovy JDK extensions.
Here’s a list of such operators and what they generally mean. Try not to deviate from the semantics when you do your own operator overloading!
Operator | Method | Semantics |
---|---|---|
|
a.plus(b) |
Addition |
|
a.minus(b) |
Subtraction |
|
a.multiply(b) |
Multiplication |
|
a.div(b) |
Division |
|
a.mod(b) |
Modulo/remainder |
|
a.power(b) |
Exponentiation |
|
a.or(b) |
Bitwise OR |
|
a.and(b) |
Bitwise AND |
|
a.xor(b) |
Bitwise XOR |
|
a.asType(b) |
Type coercion |
|
a.call() |
Method call |
|
a.getAt(b) |
Array access |
|
a.putAt(b, c) |
Array mutation |
|
b.isCase(a) |
'is one of' |
|
a.leftShift(b) |
Left shift or append |
|
a.rightShift(b) |
Right shift |
|
a.rightShiftUnsigned(b) |
Unsigned right shift |
|
a.next() |
Increment value |
|
a.previous() |
Decrement value |
|
a.positive() |
Make positive |
|
a.negative() |
Make negative |
|
a.bitwiseNegative() |
Bitwise negate |
1.4. Other operators
These operators return true
or false
based on different types of comparison.
Operator | Semantics |
---|---|
|
Value-based equality |
|
Value-based inequality |
|
Less than |
|
Less than or equal |
|
Greater than |
|
Greater than or equal |
|
Compare (returns -1, 0, or 1 if |
|
Regex pattern match. Returns a |
|
Regex pattern exact match. Returns |
|
Null-safe navigation. Returns |
|
Ternary operator (concise if-else). Returns |
|
Elvis operator. Returns value of |
2. Flow control
This section covers conditions, loops, and error handling via exceptions.
2.1. Conditions
The most common conditional in Groovy is the if
statement:
if (<expr>) { (1)
...
}
else if (<expr>) { (2)
...
}
else { (3)
...
}
-
Only the
if
is required and must come first. -
You can have as many
else if
as you like. -
You can only have a single
else
and it must come last.
Other notes:
-
The curly braces are optional if the body of the block is only a single statement.
-
<expr> must resolve to
true
orfalse
according to Groovy Truth (see next sub section).
The only alternative is the switch
statement, which is like an extended if-else if-else
:
switch (<value>) {
case <value>: (1)
...
break (2)
case <value>: (3)
...
break
default: (4)
...
break
}
-
Matches if this value is the same as the one in the
switch
. More generally, matches ifcaseValue.isCase(switchValue)
evaluates totrue
. -
break
is not required but without it, the followingcase
will always trigger too. -
You can have as many
case
statements as you like. -
If none of the
case
statements match, this will trigger. It is not required.
2.2. Groovy Truth
Groovy will automatically coerce expressions to boolean values where a boolean is required, for example in an if
statement. Here are some standard coercions:
Type | Values equating to false |
Values equating to true |
---|---|---|
String |
Empty or |
Everything else |
Number |
Zero or |
Everything else |
Collection |
Empty or |
Everything else |
Map |
Empty or |
Everything else |
Matcher ( |
No match found |
At least one match |
2.3. Loops
Groovy has two main loops: for
and while
. There is no do-while
. The predominant syntax for the for
loop is:
for (<var> in <value>) {
...
}
where <var> is a typed or untyped variable and <value> is something that can be iterated over, such as a list or a range of numbers. For example, iterating over numbers can be done with:
for (int i in 0..<10) {
...
}
Here’s an example of iterating over a list of strings:
List<String> listOfNames = ...
for (name in listOfNames) {
...
}
Note The above form of for
works for any instance of java.lang.Iterable
, such as collections and strings.
There is a less common form of the for
loop which mimics the behaviour of Java:
for (int i = 0; i < 10; i += 2) {
...
}
This is rarely used and should be avoided if possible. It doesn’t support the ,
operator that allows initialisation of multiple variables, so it’s not completely consistent with Java. That makes is confusing for people coming from that language.
The while
loop is straightforward:
while (<expr>) {
...
}
where <expr> is an expression that can be evaluated to a boolean according to Groovy Truth.
For completeness, another common approach to iteration is with the each()
method:
List<String> listOfNames = ...
listOfNames.each { String name ->
...
}
One notable disadvantage of this approach is that Groovy can’t infer the type of the objects in the iterable, so it’s often best to explicitly declare the type of the closure argument. See later for more closure syntax.
2.4. Exceptions
The normal mechanism for error handling in Groovy is via exceptions, same as for Java. Unlike Java, though, Groovy treats all exceptions as runtime ones, which means the compiler does not force you to catch them.
Here is the basic syntax:
try {
// Execute the code that might throw an exception
}
catch (SpecficException ex) { (1)
// Do something with the exception `ex`
}
catch (GenericException ex) {
...
}
finally { (2)
...
}
-
Catch expressions are evaluated in declared order, so the first one that matches the thrown exception wins. Hence you normally order them from most specific to least specific.
-
The
finally
block always executes, regardless of whether the code throws an exception or not.
Note The try
is required, but the catch
and finally
blocks are optional. You have to have at least one catch
or a finally
, though.
Throwing an exception is even easier:
throw new MyException()
In other words, you instantiate an exception just like any other object and use it as the argument to throw
. You can also use throw
to rethrow an exception from a catch
block. And just as you can pass arguments when creating normal objects, you can do the same with exceptions. One of the most common arguments (supported by most exceptions) is a message explaining the error:
throw new ConnectException("Credentials are invalid")
If you want to execute the same block of code for more than one different exception, you can use a multi-catch block:
try {
// Execute the code that might throw an exception
}
catch (SpecficException | OtherException ex) {
// Do something with the exception `ex`
}
So in general, a catch takes the form:
catch (<type> [| <type>]* <var>) { ... }
where * indicates 0 or more of what’s in the square brackets.
3. Classes and objects
Groovy is an object-oriented language whose custom types are known as classes. It also support interfaces, which have no implementation and simply define a contract between the caller and callee. In other words, one or more defined method signatures.
3.1. Class definitions
[package <pkg>] (1)
[<scope>] [abstract|final] class ClassName [extends OtherClass]
[implements FirstInterface, SecondInterface] {
[<scope>] [static] [final] def|<type> fieldName [= <value>] (2)
[<scope>] ClassName([<args]) { (3)
// Body
}
[<scope>] [static] [final] def|<type>|void methodName([<args>]) { (4)
// Method body
}
[<scope>] [abstract] def|<type>|void methodName([<args>]) (5)
}
-
Optional package/namespace for the class. Ideally all classes should be in a package.
-
Declares a field or property (see properties section) for storing state. Cardinality: 0..*
-
Declares a constructor that allows you to initialise new instances of the class.
-
Defines a method implementation that can be called from other code.
-
Declares an abstract method, i.e. one that has no implementation and must be implemented by subclasses.
Legend:
-
[…] = something that’s optional.
-
…|… = indicates mutually exclusive options.
-
<pkg> = a dot-separated namespace, e.g. org.example or java.lang.
-
<scope> = a visibility scope that determines what other code has access to the class/field/method. Groovy defaults to
public
, i.e. all code has access.protected
is accessible from subclasses and code in the same package (packages are not hierarchical).private
is only accessible from the same class.protected
andprivate
do not apply to classes. -
<abstract> = applies to classes (they can’t be instantiated directly) and methods (they have no implementation and must be implemented in subclasses). If a class has at least one abstract method, it is automatically an abstract class.
-
<final> = declares that a class cannot be subclassed or that a method cannot be overridden.
-
<static> = declares a field that is shared between all instances of the class, or a method that can be called on the class itself, not an instance of the class.
-
<type> = an explicit type, such as
String
orint
. -
<value> = an initial value for a field or property (can be an expression too).
-
<args> = a comma-separated list of method arguments. Each argument is of the form
[<type>] <name>
. Cardinality: 0..*. -
extends = declares that this class subclasses another class. You cannot extend more than one class.
-
implements = declares that this class implements the methods defined in the listed interfaces. You can implement as many interfaces as you like.
Here’s an example of a simple class with a property and method:
class Person {
String name
Date dateOfBirth
int getAge() {
return (new Date() - dateOfBirth).intdiv(365)
}
}
Remember that you can replace the types in front of the property names by def
if you want to leave them untyped.
3.2. Objects
Objects are instances of classes. To create new objects, you can either use literals, such as those described in the Type list, or the new
keyword:
def p = new Person()
The new
keyword allows you to instantiate any non-abstract class, while optionally initialising its state. How you initialise the object depends on what constructors are defined. In the case of no constructors or a single default (zero-arg) constructor, you can use GroovyBeans syntax:
def p = new Person(name: "John Doe", dateOfBirth: ...)
3.3. Properties
Properties are an extension of fields based on the JavaBeans API. When you access properties, you always go through getter and setter methods. Groovy automatically generates those underlying methods:
def p = new Person(...) // All of these work println "${p.name} (${p.dateOfBirth})" println "${p.getName()} (${p.getDateOfBirth()})" p.name = "Peter" p.setName("John")
Read-only properties are implemented as standalone getter methods:
class Person {
...
String getDisplayDetails() {
return "${name} (${dateOfBirth})"
}
}
def p = ...
println p.displayDetails
Adding a visibility scope to a field disables property behavior, i.e. the getter and setter methods aren’t generated:
class Person {
public String name
}
def p = new Person(name: "Peter")
println p.getName() // Throws MissingMethodException!
The GroovyBeans constructor syntax still works, though. Here are some examples of how property names maps to methods:
Property name | Method name |
---|---|
|
|
|
|
|
|
|
|