Skip to content
Skip to breadcrumbs
Skip to header menu
Skip to action menu
Skip to quick search
Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Dashboard
Groovy
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<p>Groovy uses a similar syntax to Java although in Groovy semicolons are optional.<br /> This saves a little typing but also makes code look much cleaner (surprisingly so for such a minor change). So normally if one statement is on each line you can ommit semicolons altogether - though its no problem to use them if you want to. If you want to put multiple statements on a line use a semicolon to separate the statements.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def x = [1, 2, 3] println x def y = 5; def x = y + 7 println x assert x == 12 </pre></td></tr></table><p>If the end of the line is reached and the current statement is not yet complete it can be spanned across multiple lines. So for things like method parameters or creating lists or for complex if expressions you can span multiple lines.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def x = [1, 2, 3, 4, 5, 6] println( x ) if (x != null && x.size() > 5) { println("Works!") } else { assert false: "should never happen ${x}" } </pre></td></tr></table><h2>Multiple assignments</h2><p>The previous code snippets showed some examples of assignments, but Groovy also supports multiple assignments. </p><p>In Groovy 1.6, there is only one syntax addition for being able to define and assign several variables at once:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def (a, b) = [1, 2] assert a == 1 assert b == 2 </pre></td></tr></table><p>A more meaninful example may be methods returning longitute and latitude coordinates. If these coordinates are represented as a list of two elements, you can easily get back to each element as follows:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def geocode(String location) { // implementation returns [48.824068, 2.531733] for Paris, France [48.824068, 2.531733] } def (_lat, _long) = geocode("Paris, France") assert _lat == 48.824068 assert _long == 2.531733 </pre></td></tr></table><p>And you can also define the types of the variables in one shot as follows:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def (int i, String s) = [1, 'Groovy'] assert i == 1 assert s == 'Groovy' </pre></td></tr></table><p>For the assignment (with prior definition of the variables), just omit the def keyword:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def firstname, lastname (firstname, lastname) = "Guillaume Laforge".tokenize() assert firstname == "Guillaume" assert lastname == "Laforge" </pre></td></tr></table><p>If the list on the right-hand side contains more elements than the number of variables on the left-hand side, only the first elements will be assigned in order into the variables. Also, when there are less elements than variables, the extra variables will be assigned null.</p><p>So for the case with more variables than list elements, here, c will be null:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def elements = [1, 2] def (a, b, c) = elements assert a == 1 assert b == 2 assert c == null </pre></td></tr></table><p>Whereas in the case where there are more list elements than variables, we'll get the following expectations:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def elements = [1, 2, 3, 4] def (a, b, c) = elements assert a == 1 assert b == 2 assert c == 3 </pre></td></tr></table><p>For the curious minds, supporting multiple assignments also means we can do the standard school swap case in one line:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>// given those two variables def a = 1, b = 2 // swap variables with a list (a, b) = [b, a] assert a == 2 assert b == 1 </pre></td></tr></table><h2>Comments</h2><p>The characters "//" begin a comment that last for the rest of the line.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>print "hello" // This is a silly print statement </pre></td></tr></table><p>The characters "/<strong>*" begin a comment that lasts until the first "</strong>*/".</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>/* This is a long comment about our favorite println */ println "hello" </pre></td></tr></table><p>The character "#" is not a comment character.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>// This doesn't work: # Bad comment </pre></td></tr></table><h2>Method calls</h2><p>Method calling syntax is similar to Java where methods can be called on an object (using dot) or a method on the current class can be called. Static and instance methods are supported.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>class Foo { def calculatePrice() { 1.23 } static void main(args) { def foo = new Foo() def p = foo.calculatePrice() assert p > 0 println "Found price: " + p } } </pre></td></tr></table><p>Notice that the <em>return</em> statement is optional at the end of methods. Also you don't need to specify a return type (it will default to Object in the bytecode if none is specified).</p><h2>Optional parenthesis</h2><p>Method calls in Groovy can omit the parenthesis if there is at least one parameter and there is no ambiguity.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>println "Hello world" System.out.println "Nice cheese Gromit!" </pre></td></tr></table><p>It is also possible to omit parenthesis when using named arguments. This makes for nicer DSLs:</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>compare fund: "SuperInvestment", withBench: "NIKEI" monster.move from: [3,4], to: [4,5] </pre></td></tr></table><h2>Named parameter passing</h2><p>When calling a method you can pass in named parameters. Parameter names and values are separated by a colon (like the Map syntax) though the parameter names are identifiers rather than Strings.</p><p>Currently this kind of method passing is only implemented for calling methods which take a Map or for constructing JavaBeans.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def bean = new Expando(name:"James", location:"London", id:123) println "Hey " + bean.name assert bean.id == 123 </pre></td></tr></table><h2>Passing closures into methods</h2><p>Closures are described in more detail</p><table class="wysiwyg-macro" data-macro-name="unmigrated-inline-wiki-markup" data-macro-parameters="atlassian-macro-output-type=BLOCK" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3VubWlncmF0ZWQtaW5saW5lLXdpa2ktbWFya3VwOmF0bGFzc2lhbi1tYWNyby1vdXRwdXQtdHlwZT1CTE9DS30&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>{link:here|closures}{link}</pre></td></tr></table><p>.</p><p>Closures can be passed into methods like any other object</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def closure = { param -> param + 1 } def answer = [1, 2].collect(closure) assert answer == [2, 3] </pre></td></tr></table><p>Though there is some syntax sugar to make calling methods which take a closure easier. Instead of specifying parenthesis, you can just specify a closure. e.g.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>answer = [1, 2].collect { param -> param + 1 } assert answer == [2, 3] </pre></td></tr></table><p>The above code is equivalent to the previous code, just a little more groovy. If a method takes parameters you can leave the closure outside of the parenthesis (provided that the closure parameter is the last parameter on the underlying method).</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def value = [1, 2, 3].inject(0) { count, item -> count + item } assert value == 6 </pre></td></tr></table><p>The above code is equivalent to the following (but just neater)</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def value = [1, 2, 3].inject(0, { count, item -> count + item }) assert value == 6 </pre></td></tr></table><h2>Important Note</h2><p>Note that when using the neater syntax for specifying closures either without parenthesis or by specifying the closure after the parenthesis, the closure must start on the same line. i.e. the { symbol must be on the same line as the method call statement. Otherwise the parser interprets the { as a start of a block.</p><p>For a in depth description of what kind of method signatures Groovy supports see the <a class="confluence-link" href="/display/GROOVY/Extended+Guide+to+Method+Signatures" data-linked-resource-id="97976422" data-linked-resource-type="page" data-linked-resource-default-alias="Extended Guide to Method Signatures" data-base-url="http://docs.codehaus.org">Extended Guide to Method Signatures</a></p><h2>Dynamic method dispatch</h2><p>Groovy always uses dynamic dispatch, even if a variable is constrained by a type. The type of the variable only ensures that the variable is at least of that type and avoids you assigning a String to for example int. Dynamic method dispatch is often referred to as <em>dynamic typing</em> whereas Java uses <em>static typing</em> by default.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def dynamicObject = "hello world".replaceAll("world", "Gromit") dynamicObject += "!" assert dynamicObject == "hello Gromit!" String staticObject = "hello there" staticObject += "!" assert staticObject == "hello there!" </pre></td></tr></table><h2>Properties</h2><p>These are described in more detail in the <a class="confluence-link" href="/display/GROOVY/Groovy+Beans" data-linked-resource-id="2716" data-linked-resource-type="page" data-linked-resource-default-alias="Groovy Beans" data-base-url="http://docs.codehaus.org">Groovy Beans</a> section.<br /> To access properties you use dot with the property name. e.g.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def bean = new Expando(name:"James", location:"London", id:123) def name = bean.name println("Hey ${name}") bean.location = "Vegas" println bean.name + " is now in " + bean.location assert bean.location == "Vegas" </pre></td></tr></table><p>The above uses a special bean called Expando which allows properties to be added dynamically at runtime.</p><p>An Expando is a Map which behaves as a dynamic bean: adding new key/value pairs add the equivalent getter and setter methods, as if they were defined in a real bean.</p><h2>Safe navigation</h2><p>If you are walking a complex object graph and don't want to have NullPointerExceptions thrown you can use the ?. operator rather than . to perform your navigation.</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="java" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>def foo = null def bar = foo?.something?.myMethod() assert bar == null </pre></td></tr></table>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced