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
Sign Up
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
<h1>Informal Guide</h1> <p>When using the Java programming language most executable code is enclosed in either static class methods or instance methods. (Code can also be enclosed in constructors, initializers, and initialization expressions, but those aren't important here.) A method encloses code within curly brackets and assigns that block of code a method name. All such methods must be defined inside of a class of some type. For example, if you were to write a method that returned the square of any integer it may look like this:</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> package example.math; public class MyMath { public static int square(int numberToSquare){ return numberToSquare * numberToSquare; } } </pre></td></tr></table> <p>Now in order to use the square() method you need to reference the class and the method by name as follows:</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> import example.math.MyMath; ... int x, y; x = 2; y = MyMath.square(x); // y will equal 4. </pre></td></tr></table> <p>You can do the same thing in Groovy, but in groovy you can alternatively define the code without having to declare a class and a method as follows:</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> { numberToSquare -> numberToSquare * numberToSquare } </pre></td></tr></table> <p>In Groovy, this anonymous code block is referred to as a <strong>closure</strong> definition (see the Formal Guide section below for a more elaborate definition of terms). A closure definition is one or more program statements enclosed in curly brackets. A key difference between a closure and method is that closures do not require a class or a method name.</p> <p>As you can see, the executable code is the same except you didn't need to declare a class or assign the code a method name. While illustrative, the previous example is not all that useful because there is no way to use that closure once its created. It has no identifier (method name) so how can you call it? To fix that you assign the closure to a variable when it's created. You can than treat that variable as the identifier of the closure and make calls on it.</p> <p>The following shows the <code>square()</code> method re-written as a closure:</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 = 2 // define closure and assign it to variable 'c' def c = { numberToSquare -> numberToSquare * numberToSquare } // using 'c' as the identifer for the closure, make a call on that closure def y = c(x) // shorthand form for applying closure, y will equal 4 def z = c.call(x) // longhand form, z will equal 4 </pre></td></tr></table> <p>What is really nice about closures is that you can create a closure, assign it to a variable, and then pass it around your program like any other variable. At first this seems a bit, well useless, but as you learn more about Groovy you'll discover that closures are used all over the place.</p> <p>As an example, let's extend the <code>java.util.Vector</code> class from Java by adding a single method that allows you to apply a closure to every element in the vector. My new class, GVector, looks as follows:</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> package example public class GVector extends java.util.Vector { public void apply( c ){ for (i in 0..<size()){ this[i] = c(this[i]) } } } </pre></td></tr></table> <p>The <code>apply()</code> method takes a closure as an input parameter. For each element in the <code>GVector</code>, the closure is called passing in the element. The resulting value is then used to replace the element. The idea is that you can modify the contents of the <code>GVector</code> in place using a closure which takes each element and converts into something else.</p> <p>Now we can call our new <code>apply()</code> method with any closure we want. For example, we will create a new <code>GVector</code>, populate it with some elements, and pass in the closure we created earlier, the one that squares an integer value.</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> import example def gVect = new GVector() gVect.add(2) gVect.add(3) gVect.add(4) def c = { numberToSquare -> numberToSquare * numberToSquare } gVect.apply(c) // the elements in the GVector have all been squared. </pre></td></tr></table> <p>Because the apply() method on the GVector can be used with any closure, you can use any closure. For example, the following uses a closure that simply prints out the item its passed.</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> import example def gVect = new GVector() gVect.add(2) gVect.add(3) gVect.add(4) def c2 = { value -> println(value) } gVect.apply(c2) // the elements in the GVector have all been printed. </pre></td></tr></table> <p>If you were to run the above script, assuming <code>GVector</code> from earlier is on your classpath, the output would look like this:</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="none" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6bm9uZX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> C:/> groovy myscript.groovy 4 9 16 C:/> </pre></td></tr></table> <p>In addition to assigning closures to variables, you can also declare them directly as arguments to methods. For example, the above code could be re-written in the following manner:</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> import example def gVect = new GVector() gVect.add(2) gVect.add(3) gVect.add(4) gVect.apply{ value -> println(value) } // elements in GVector have been printed. </pre></td></tr></table> <p>This example accomplishes the same thing as the first, but the closure is defined directly as an argument to the apply method of GVector.</p> <p>The other important difference of a closure to a normal method is that a closure can refer to variables from the scope in which it is called (in fact this is where this language construct gets its name). Here is an example:</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 Employee { def salary } def highPaid(emps) { def threshold = 150 return emps.findAll{ e -> e.salary > threshold } } def emps = [180, 140, 160].collect{ val -> new Employee(salary:val) } println emps.size() // prints 3 println highPaid(emps).size() // prints 2 </pre></td></tr></table> <p>In this example, the closure block { e -> e.salary > threshold } refers to the <code>threshold</code> variable defined in the <code>highPaid()</code> method. The example also used a closure to create the <code>emps</code> list.</p> <h3>Simulate Javascript-style variable arguments</h3> <p>Groovy supports varargs as Closure parameter, but that requires the use of a Object[] and the closure code has to access the varargs as an Array. </p> <p>In JavaScript, function arguments are fully dynamic and you could call a function with any number of arguments different from the number of arguments defined in a function, e.g.</p> <table class="wysiwyg-macro" data-macro-name="code" data-macro-default-parameter="javascript" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6amF2YXNjcmlwdH0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre> //javascript function doSomething( var0, var1){ alert( 'var0: ' + var0 + ', var1: ' + var1); } doSomething( 'value0', 'value1', 'value2' ); //one argument more than in the defined function </pre></td></tr></table> <p>If your closure defined more argument than closure call, then you could use:</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 doSomething = {var0, var1 = null -> } doSomething( 'value0' ) doSomething( 'value0' , 'value1') </pre></td></tr></table> <p>However, you can't do the job exactly like a JavaScript function when your closure has defined less argument than the closure call. If you are the implementer of the closure, you could use varargs (as described in the <a class="confluence-link" href="/display/GROOVY/Closures+-+Formal+Definition" data-linked-resource-id="11403384" data-linked-resource-type="page" data-linked-resource-default-alias="Closures - Formal Definition" data-base-url="http://docs.codehaus.org">Formal Guide</a>) to allow your closure to take more arguments than it is defined, and you have to access the extra variables as an Object[].</p> <p>There are cases you may want to take more arguments but not using varargs/Object[]. For example, as an API provider, you expose an API that take a closure as argument. The closure may define one or two parameters up to the user. (this is a typical case when passing JavaScript function) The following is an example about how to simulate such behaivior:</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> // sample entity class User{ def username, password, version, salt = 'RANDOM'; } // your API, provide a Map of changes to update a entity. the map value may be static value, or a closure that take up to 2 params def update( entity, Map changes ){ changes?.each {k, v -> def newValue; if (v instanceof Closure){ switch (v.parameterTypes.length) { case 0: newValue = v(); break; case 1: newValue = v(entity[k]); break; // if one params, the closure is called with the field value case 2: newValue = v(entity[k],entity); break; // if two params, the closure is called with teh field value and the entity } }else{ newValue = v } entity[k] = newValue } } // user code def user1 = new User(username:'user1', password:'pass1', version:0) update( user1, [password:{p,e-> Hash.md5(p, e.salt) }, version:{v-> v+1 }] //assume there is a MD5 util </pre></td></tr></table> <h3>Other Examples</h3> <ul> <li>You could define a closure that take a closure as argument, and combine the use of other Groovy techniques to do a lot of things. See the <a class="confluence-link" href="/display/GROOVY/TMPGroovy+Categories#TMPGroovyCategories-AdvancedUsage" data-anchor="AdvancedUsage" data-linked-resource-id="27920" data-linked-resource-type="page" data-linked-resource-default-alias="TMPGroovy Categories#AdvancedUsage" data-base-url="http://docs.codehaus.org">Closure, Category and JPA example</a></li> </ul> <h2>Closures vs. Code Blocks</h2> <p>A closure looks a lot like a regular Java or Groovy code block, but actually it's not the same. The code within a regular code block (whether its a method block, static block, synchronized block, or just a block of code) is executed by the virtual machine as soon as it's encountered. With closures the statements within the curly brackets are not executed until the call() is made on the closure. In the previous example the closure is declared in line, but it's not executed at that time. It will only execute if the call() is explicitly made on the closure. This is an important differentiator between closures and code blocks. They may look the same, but they are not. Regular Java and Groovy blocks are executed the moment they are encountered; closures are only executed if the call() is invoked on the closure.</p>
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