What you need to know about the Safe Navigation operator in Apache Groovy

This valuable tool will help you write more robust, concise and readable code.
Home » Blog » What you need to know about the Safe Navigation operator in Apache Groovy

The Safe Navigation operator is a valuable tool for anyone using Groovy. By learning this operator, you can write more robust, concise, and readable code, while also leveraging unique features of the Groovy language.

In the previous article in this series, you learned about Groovy’s implementation of the ternary operator and the related Elvis operator. Groovy has one more trick up its sleeve that works to streamline ternary and Elvis operators even further. It also helps to avoid null pointer exceptions at runtime: this is the safe navigation operator.  (If you haven’t installed Groovy yet, please read the intro to this series.)

The script below, modified from the last article, shows how the Safe Navigation operator works:

1  String strParam = "42"
2  int intParam = strParam?.isInteger() ? Integer.parseInt(strParam):0
3  println "strParam = '$strParam' intParam = $intParam"
4  strParam = "xyz"
5  intParam = strParam?.isInteger() ? Integer.parseInt(strParam) : 0
6  println "strParam = '$strParam' intParam = $intParam"
7  strParam = null
8  intParam = strParam?.isInteger() ? Integer.parseInt(strParam) : 0
9  println "strParam = '$strParam' intParam = $intParam"

See the expression above:

 strParam?.isInteger()

In detail, Groovy first checks that strParam is not null, not blank, not zero, and not empty. In other words, the Groovy truth, but only if it passes those tests and its .isInteger() method is called. Recall that you arrived here from first changing:

 strParam != null && strParam.isInteger()

to:

 strParam && strParam.isInteger()

using the Groovy truth, you are at:

 strParam?.isInteger()

This Safe Navigation operator ?. scores big on the DRY scale. But aside from being more compact and therefore readable, it also avoids introducing errors by testing one thing in one place and a different thing in another. For example, it can test two similar variable names. Finally, it’s not possible to generate a null pointer exception when using the safe navigation operator, which is always a good thing.

When you run this, you see:

 $ groovy Groovy08a.groovy
 strParam = ‘42' intParam = 42
 strParam = ‘xyz' intParam = 0
 strParam = ‘null' intParam = 0

Groovy 3 has also implemented the safe index access operator ?[] to provide the same kind of kind of protection when attempting to access elements of arrays, lists and maps:

 1  def l = [0,1,2,3]
 2  println "l?[4] ${l?[4]}"
 3  def l2 = null
 4  println "l2?[4] ${l2?[4]}"
 5  def m = ['Monday': 42, 'Tuesday': 33]
 6  println "m?['Wednesday'] ${m?['Wednesday']}"
 7  println "m?.Wednesday ${m?.Wednesday}"
 8  def m2 = null
 9  println "m2?['Wednesday'] ${m2?['Wednesday']}"
10  println "m2?.Wednesday ${m2?.Wednesday}"

Here the safe index and safe navigation operators are protecting against attempts to use lists or maps that haven’t yet been initialized:

$ groovy Groovy08b.groovy
l?[4] null
l2?[4] null
m?[‘Wednesday'] null
m?.Wednesday null
m2?[‘Wednesday'] null
m2?.Wednesday null

Conclusion

Groovy truth, the ternary, Elvis operators, Safe Navigation and index operators, when taken together, move Groovy syntax and semantics to a whole new level. Unwieldy Java expressions shorten up by eliminating repeated use of the same variable names and become completely practical as a replacement for ifthenelse. This facilitates modalities of expression that are more functional — for example to return values of methods or closures. The added DRYness removes opportunities to use the wrong variable name in the right place. The readability, and therefore maintainability, improves.

In short, these are three more significant contributions to making Groovy, groovy.

Photo by Jimmy Nilsson Masth on Unsplash

Author

If you enjoyed this post, you might also enjoy these