ZetCode

Groovy Null-Safe Operators

last modified October 15, 2026

Null references are a common source of NullPointerException in Java. Groovy offers operators that let you navigate through possibly empty values without writing nested if checks. This tutorial covers the safe navigation operator ?., the Elvis operator ?:, and the spread operator *..

Safe Navigation Operator

The safe navigation operator ?. calls a method or accesses a property only when the object on the left is not null. If the object is null, the whole expression evaluates to null.

NullSafeNavigation.groovy
class Address { String city }
class Person { String name; Address address }

def p1 = new Person(name: "Alice", address: new Address(city: "Paris"))
def p2 = new Person(name: "Bob", address: null)
def p3 = null

println p1?.address?.city
println p2?.address?.city
println p3?.name
println p2?.name?.toUpperCase()

p2.address is null, so p2?.address?.city stops at the first null and returns null instead of throwing an exception. The same applies to p3 and to the method call toUpperCase() on a null name.

Elvis Operator

The Elvis operator ?: returns the value on its left when that value is true in the Groovy sense, and the value on its right otherwise. Since null, empty strings, and empty collections are false in Groovy, it is a compact way to supply defaults.

ElvisOperator.groovy
class Address { String city }
class Person { String name; Address address }

def p2 = new Person(name: "Bob", address: null)

def city = p2.address?.city ?: "Unknown"
println city

def name = "" ?: "Anonymous"
println name

When p2.address is null, the expression p2.address?.city is null too, so the Elvis operator supplies "Unknown". Combining the two operators is the usual pattern for optional nested data, such as a user profile read from JSON.

Spread Operator

The spread operator *. applies a property access or method call to every element of a collection and returns a new list. It is shorthand for collect, and it also handles null elements safely when combined with ?..

SpreadOperator.groovy
class Address { String city }
class Person { String name; Address address }

def people = [
    new Person(name: "Alice", address: new Address(city: "Paris")),
    new Person(name: "Bob", address: null)
]

println people*.name
println people*.address*.city
println people.collect { it?.address?.city }

people*.name produces [Alice, Bob]. The second line produces [Paris, null], because a null address fails the navigation for that element only. Using ?. inside a collect closure gives the same result with more explicit control.

Null-Safe Method Calls on Lists

Calling a method on a null list throws an exception. Guard it with ?. and supply an empty list with ?: when you want safe iteration.

SafeIteration.groovy
def findTags(List tags) {
    (tags ?: []).findAll { it.startsWith("g") }
}

println findTags(["groovy", "java", "gradle"])
println findTags(null)

def maybe = null
println maybe?.size() ?: 0

Passing null to findTags returns an empty list rather than failing. The last line shows the common idiom of combining ?. with ?: to get a default count.

Best Practices

Source

Groovy Operators Documentation

Null-safe operators let you write chained access that reads naturally while still handling missing values. Together, ?., ?:, and *. cover most of the null checks that Java code needs.

Author

My name is Jan Bodnar, and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Groovy tutorials.