Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In Groovy, the last expression evaluated in the body of a method can be returned without necessiting the 'return' keyword. specially for short methods and for closures, it's nicer to omit it for brevity:

Code Block

String toString() { return "a server" }
String toString() { "a server" }

But sometimes, this doesn't look to good when you're using a variable, and see it visually twice on two rows:

Code Block

def props() {
    def m1 = [a: 1, b: 2]
    m2 = m1.findAll { k, v -> v % 2 == 0 }
    m2.c = 3
    m2
}

...

Statements like if/else, try/catch can thus return a value as well, as there's a "last expression" evaluated in those statements:

Code Block

def foo(n) {
    if(n == 1) {
        "Roshan"
    } else {
        "Dawrani"
    }
}

assert foo(1) == "Roshan"
assert foo(2) == "Dawrani"

...

So don't write:

Code Block

def String name = "Guillaume"

But:

Code Block

String name = "Guillaume"

When using def in Groovy, the actual type holder is Object (so you can assign any object to variables defined with def, and return any kind of object if a method is declared returning def).

When defining a method with untyped parameters, you can use 'def' but it's not needed, so we tend to omit them. So instead of:

Code Block
void doSomething(def param1, def param2) { }

Prefer:

Code Block
void doSomething(param1, param2) { }

But as we mention in the last section of the document, it's usually better to type your method parameters, so as to help with documenting your code, and also help IDEs for code-completion, or for leveraging the static type checking or static compilation capabilities of Groovy.

Another place where 'def' is redundant and should be avoided is when defining constructors:

Code Block
class MyClass {
    def MyClass() {}
}

Instead, just remove the 'def':

Code Block
class MyClass {
    MyClass() {}
}

Public by default

By default, Groovy considers classes and methods 'public'. So you don't have to use the 'public' modifier everywhere something is public. Only if it's not public, you should put a visibility modifier.

So instead of:

Code Block

public class Server {
    public String toString() { return "a server" }
}

Prefer the more concise:

Code Block

class Server {
    String toString() { "a server" }
}

You may wonder about the 'package-scope' visibility, and the fact Groovy allows one to omit 'public' means that this scope is not supported by default, but there's actually a special Groovy annotation which allows you to use that visibility:

Code Block

class Server {
    @PackageScope Cluster cluster
}

...

Groovy allows you to omit the parentheses for top-level expressions, like with the println command:

Code Block

println "Hello"
method a, b

vs:

Code Block

println("Hello")
method(a, b)

When a closure is the last parameter of a method call, like when using Groovy's 'each‘ iteration mechanism, you can put the closure outside the closing parens, and even omit the parentheses:

Code Block

list.each( { println it } )
list.each(){ println it }
list.each  { println it }

...

There are some cases where Groovy doesn't allow you to remove parentheses. As I said, top-level expressions can omit them, but for nested method calls or on the right-hand side of an assignment, you can't omit them there.

Code Block

def foo(n) { n }

println foo 1 // won't work
def m = foo 1

...

The .class suffix is not needed in Groovy, a bit like in Java's instanceof.

For example:

Code Block

connection.doPost(BASE_URI + "/modify.hqu", params, ResourcesResponse.class)

Using GStrings we're going to cover below, and using first class citizens:

Code Block

connection.doPost("${BASE_URI}/modify.hqu", params, ResourcesResponse)

...

In Groovy, a getters and setters form what we call a "property", and offers a shortcut notation for accessing and setting such properties. So instead of the Java-way of calling getters / setters, you can use a field-like access notation:

Code Block

resourceGroup.getResourcePrototype().getName() == SERVER_TYPE_NAME
resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME

resourcePrototype.setName("something")
resourcePrototype.name = "something"

When writing your beans in Groovy, often called POGOs (Plain Old Groovy Objects), you don't have to create the field and getter / setter yourself, but let the Groovy compiler do it for you.

So instead of:

Code Block

class Person {
    private String name
    String getName() { return name }
    void setName(String name) { this.name = name }
}

You can simply write:

Code Block

class Person {
    String name
}

...

With a bean like:

Code Block

class Server {
    String name
    Cluster cluster
}

Instead of setting each setter in subsequent statements as follows:

Code Block

def server = new Server()
server.name = "Obelix"
server.cluster = aCluster

You can use named parameters with the default constructor (first the constructor is called, then the setters are called in turn):

Code Block

def server = new Server(name: "Obelix", cluster: aCluster)

...

Named-parameters with the default constructor is interesting when creating new instances, but what if you are updating an instance that was given to you, do you have to repeat the 'server' prefix again and again? No, thanks to the with() method that Groovy adds on all objects of any kind:

Code Block

server.name = application.name
server.status = status
server.sessionCount = 3
server.start()
server.stop()

vs:

Code Block

server.with {
    name = application.name
    status = status
    sessionCount = 3
    start()
    stop()
}

...

Java's == is actually Groovy's is() method, and Groovy's == is a clever equals()!
To compare the references of objects, instead of ==, you should use a.is(b).
But to do the usual equals() comparison, you should prefer Groovy's ==, as it also takes care of avoiding NullPointerException, independently of whether the left or right is null or not.

Instead of:

Code Block

status != null && status.equals(ControlConstants.STATUS_COMPLETED)

Do:

Code Block

status == ControlConstants.STATUS_COMPLETED

...

We often use string and variable concatenation in Java, with many opening / closing of double quotes, plus signs, and \n characters for newlines. With interpolated strings (called GStrings), such strings look better and are less painful to type:

Code Block

throw new Exception("Unable to convert resource: " + resource)

vs:

Code Block

throw new Exception("Unable to convert resource: ${resource}")

Inside the curly braces, you can put any kind of expression, not just variables. For simple variables, or variable.property, you can even drop the curly braces:

Code Block

throw new Exception("Unable to convert resource: $resource")

You can even lazily evaluate those expressions using a closure notation with ${-> resource }. When the GString will be coerced to a String, it'll evaluate the closure and get the toString() representation of the return value. Example:

Code Block

int i = 3

def s1 = "i's value is: ${i}"
def s2 = "i's value is: ${-> i}"

i++

assert s1 == "i's value is: 3" // eagerly evaluated, takes the value on creation
assert s2 == "i's value is: 4" // lazily evaluated, takes the new value into account

When strings and their concatenated expression are long in Java:

Code Block

throw new PluginException("Failed to execute command list-applications:" +
    " The group with name " +
    parameterMap.groupname[0] +
    " is not compatible group of type " +
    SERVER_TYPE_NAME)

You can use the \ continuation character (this is not a multiline string):

Code Block

throw new PluginException("Failed to execute command list-applications: \
The group with name ${parameterMap.groupname[0]} \
is not compatible group of type ${SERVER_TYPE_NAME}")

Or using multiline strings with triple quotes:

Code Block

throw new PluginException("""Failed to execute command list-applications:
    The group with name ${parameterMap.groupname[0]}
    is not compatible group of type ${SERVER_TYPE_NAME)}""")

...

Here are some examples of those native constructs:

Code Block

def list = [1, 4, 6, 9]

// by default, keys are Strings, no need to quote them
// you can wrap keys with () like [(variableStateAcronym): stateName] to insert a variable or object as a key.
def map = [CA: 'California', MI: 'Michigan']

def range = 10..20
def pattern = ~/fo*/

// equivalent to add()
list << 5

// call contains()
assert 4 in list
assert 5 in list
assert 15 in range

// subscript notation
assert list[1] == 4

// add a new key value pair
map << [WA: 'Washington']
// subscript notation
assert map['CA'] == 'California'
// property notation
assert map.WA == 'Washington'

// matches() strings against patterns
assert 'foo' =~ pattern

...

Groovy's switch is much more powerful than in C-ish languages which usually only accept primitives and assimilated. Groovy's switch accepts pretty much any kind of type.

Code Block

def x = 1.23
def result = ""
switch (x) {
    case "foo": result = "found foo"
    // lets fall through
    case "bar": result += "bar"
    case [4, 5, 6, 'inList']:
        result = "list"
        break
    case 12..30:
        result = "range"
        break
    case Integer:
        result = "integer"
        break
    case Number:
        result = "number"
        break
    default: result = "default"
}
assert result == "number"

...

To improve such situations, Groovy features import aliasing:

Code Block

import java.util.List as juList
import java.awt.List as aList

import java.awt.WindowConstants as WC

You can also import methods statically:

Code Block

import static pkg.SomeClass.foo
foo()

...

Groovy supports a variant of the . operator to safely navigate an object graph.
In Java, when you're interested in a node deep in the graph and need to check for null, you often end up writing complex if, or nested if statements like this:

Code Block

if (order != null) {
    if (order.getCustomer() != null) {
        if (order.getCustomer().getAddress() != null) {
            System.out.println(order.getCustomer().getAddress());
        }
    }
}

With ?. safe dereference operator, you can simplify such code with:

Code Block

println order?.customer?.address

...

To check your parameters, your return values, and more, you can use the 'assert' statement.
Contrary to Java's assert, asserts don't need to be activated to be working, so asserts are always checked.

Code Block

def check(String name) {
    // name non-null and non-empty according to Groovy Truth
    assert name
    // safe navigation + Groovy Truth to check
    assert name?.size() > 3
}

...

The Elvis operator is a special ternary operator shortcut which is handy to use for default values.
We often have to write code like:

Code Block

def result = name != null ? name : "Unknown"

Thanks to Groovy Truth, the null check can be simplified to just 'name'.
And to go even further, since you return 'name' anyway, instead of repeating name twice in this ternary expression, we can somehow remove what's in between the question mark and colon, by using the Elvis operator, so that the above becomes:

Code Block

def result = name ?: "Unknown"

...

If you don't really care of the exception which are thrown inside your try block, you can simply catch any of them and simply omit the type of the caught exception. So instead of catching the throwables like in:

Code Block

try {
    // ...
} catch (Throwable t) {
    // something bad happens
}

Then catch anything ('any' or 'all', or whatever makes you think it's anything):

Code Block

try {
    // ...
} catch (any) {
    // something bad happens
}

...