Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 35 Next »

Groovy uses both " and ' for strings. Either can be used. Using either type of string allows you to use strings with quotations easily.

The groovy parser supports the notation \uab12 (i.e. a leading backslash and precisely four hex digits after the 'u' ).
This notation can be used in strings or anywhere in the program like the Java parser does.


Strings may be concatenated with "+". For example:

Multi-line strings

Regular strings in Groovy cannot span multiple lines.

As an exception to this rule, a backslash at the end of a line disappears and joins the current line with the next.

If you have a block of text which you wish to use but don't want to have to encode it all (e.g. if its a block of HTML or something) then you can use the """ syntax.

Because of the leading backslash, the string text contains exactly two newlines. There are always represented by the character '\n', regardless of the line-termination conventions of the host system.

Slashy String literals

It is possible to use the another notation for String literals with the added benefit of not needing additional backslashes to escape special characters. That is especially handy with regular expressions or Windows file/directory path names.

The only escape that is supported in a slashy string is to use \/ to embed a slash into the string. A consequence of this is that you can't have a backslash as the last character of a slashy string directly (or Groovy will think you are trying to escape the closing string terminator - and hence won't think you have terminated your string). Instead use: def bs = '\\\\'; def winpath=/C:\windows\system32$bs/ or def winpath=/C:\windows\system32\${}/.

Another gotcha: don't try using an empty slashy string: def x = //, the slashes will be treated as a line comment delimiter, but def z = /${}/ would be fine.

A final gotcha: currently a slashy string can't be the left hand side (LHS) expression of an assert statement while you are eliminating the brackets, e.g.:

This is a feature of the current grammar rather than a desired goal and may one day be altered to remove this anomoly - it is a tricky edge case in the grammar.

For more examples, read about Regular Expressions.

Strings are immutable

This can be seen with these two code snips, which you can cut and paste into groovyConsole:

Above both variables are references to the map.
If you do the same thing with Strings, the behavior is different:

Here is the explanation by Guillaume Laforge:
sn and st point at the very same map object in memory in the first example, while in the second snippet, at the end, st points at a  different place in memory where there's the new immutable string.


Strings that are declared inside double-quotes (i.e. either single double-quotes or triple double-quotes for multi-line strings) can contain arbitrary expressions inside them as shown above using the ${expression} syntax in a similar way to JSP EL, Velocity and Jexl. Any valid Groovy expression can be enclosed in the ${...} including method calls etc. GStrings are defined the same way as normal Strings would be created in Java. Here is a simple example involving a simple variable and an expression:

What actually happens is whenever a string expression contains a ${...} expression then rather than a normal java.lang.String instance, a GString object is created which contains the text and values used inside the String.

GString can involve lazy evaluation so it's not until the toString() method is invoked that the GString is evaluated. This lazy evaluation is useful for things like logging as it allows the calculation of the string, the calls to toString() on the values, and the concatenation of the different strings to be done lazily if at all. Here is an example that illustrates lazy evaluation:

which outputs the following:

Thu Apr 17 23:18:17 EST 2008
It is currently Thu Apr 17 23:18:17 EST 2008
It is currently Thu Apr 17 23:18:22 EST 2008

To explain this output, we need to understand an additional rule about GStrings that we haven't covered yet. It involves different rules for evaluating a closure expression within a GString based on the number of arguments to the closure. Here are the rules:

  • If the Closure takes 0 parameters then call the Closure and use the returned value as the value at that point in the GString
  • If the Closure takes 1 parameter then call the Closure with a Writer as the parameter and use the characters written to the Writer as the value at that point in the GString
  • If the Closure takes more that one parameter throw a GroovyRuntimeException.

So, in the example above, x contains a 0 parameter closure which means that new Date() will be invoked and the value stored away as a GString value. When we attempt to print x later, that calculated value is placed in the appropriate place in the GString and output giving us the date at GString definition time. But, y contains a 1 parameter closure which means that the closure expression will be stored away in the GString. When we print out y, the closure will be invoked and give as the date at printing time.

GString Use Cases - Templating

GString is pretty handy when you don't want to use a template engine, or when you really want full lazy evaluation of GStrings. When some variable embedded in a GString, the toString() is called on that variable to get a string representation, and it's inserted into the final string. But when it's closures you embed, we don't call the toString() on closure. If that was the case, you'd get a string like "Script7$_run_closure1@8dc50e" embedded in your final string.

Instead, we distinguish two use cases:

  1. a closure with no parameter,
  2. a closure with one parameter.

And the expected behaviors:

  • For a closure with no parameter, Groovy calls the closure without parameter, and calls toString() on the result.
  • For a closure with one parameter, the parameter is actually a StringWriter to which you can append text in the body of your closure.
  • For a closure with more parameters, an exception will be thrown.



I'm executed
Executed with a class parameter
no param - one param

The embedded closure could be used in a nested manner:

GString Use Cases - GSQL

Another use case for GString is GSQL where parameters can be passed into SQL statements using this same mechanism which makes for a neat way to integrate Groovy with other languages like SQL. GroovySql then converts the expressions to ? and uses a JDBC PreparedStatement and passes the values in, preserving their types.

If you explicitly want to coerce the GString to a String you can use the toString() method. Groovy can also automatically coerce GStrings into Strings for you.

String and StringBuffer Methods

See: JN1525-Strings.

More Examples

The following example passes the test:

and outputs:

item: "bread"
item: "apple"
item: "egg"

  • No labels